PageHeap не показывает точное место сбоя - PullRequest
2 голосов
/ 08 мая 2011

Я использую PageHeap для определения повреждения кучи. Мое приложение имеет кучу повреждений. Но приложение разрывается (из-за сбоя), когда оно создает объект stl для строки, переданной методу. Я не вижу видимых проблем с памятью рядом с местом сбоя. Я включил полную страницу кучи для обнаружения повреждения кучи и / RTC для выявления повреждения стека.

Что я должен сделать, чтобы сломаться в точном месте, где происходит повреждение кучи?

Ответы [ 2 ]

1 голос
/ 20 июля 2011

Включение FULL pageheap может увеличить вероятность того, что отладчик обнаружит повреждение кучи по мере его возникновения:

gflags /p /enable /full <processname>

Кроме того, если вы можете узнать, какой адрес перезаписывается, вы можете установить точку останова на доступ к памяти в windbg. Не уверен, что отладчик VS имеет такую ​​же функцию.

0 голосов
/ 08 сентября 2013

Pageheap не всегда обнаруживает повреждение кучи именно в тот момент, когда оно происходит.

Pageheap вставляет неверную страницу сразу после выделения.Поэтому, когда вы переполняете выделенный блок, вы получаете AV.Но есть и другие возможные случаи.Одним из примеров является запись непосредственно перед распределенной структурой данных заголовка блока кучи.Заголовок блока кучи является допустимой доступной для записи памятью (скорее всего, на той же странице, что и выделенный блок).Рассмотрим следующий пример:

#include <stdlib.h>

int
main()
{
    void* block = malloc(100);
    int* intPtr = (int*)block;

    *(intPtr-1) = 0x12345; // no crash

    free(block); // crash

    return 0;
}

Итак, написание некоторого мусора непосредственно перед тем, как выделенный блок пройдет нормально.При включенном Pageheap пример разрывается внутри вызова free().Вот стек вызовов:

    verifier.dll!_VerifierStopMessage@40()  + 0x206 bytes   
    verifier.dll!_AVrfpDphReportCorruptedBlock@16()  + 0x239 bytes  
    verifier.dll!_AVrfpDphCheckNormalHeapBlock@16()  + 0x11a bytes  
    verifier.dll!_AVrfpDphNormalHeapFree@16()  + 0x22 bytes 
    verifier.dll!_AVrfDebugPageHeapFree@12()  + 0xe3 bytes  
    ntdll.dll!_RtlDebugFreeHeap@12()  + 0x2f bytes  
    ntdll.dll!@RtlpFreeHeap@16()  + 0x36919 bytes   
    ntdll.dll!_RtlFreeHeap@12()  + 0x722 bytes  
    heapripper.exe!free(void * pBlock=0x0603bf98)  Line 110 C
>   heapripper.exe!main()  Line 11 + 0x9 bytes  C++
    heapripper.exe!__tmainCRTStartup()  Line 266 + 0x12 bytes   C
    kernel32.dll!@BaseThreadInitThunk@12()  + 0xe bytes 
    ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
    ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

Pageheap включает строгие проверки согласованности кучи, но проверки не запускаются, пока не будет вызван какой-либо другой API кучи.Процедуры проверки видны в стеке.(Без Pageheap приложение, вероятно, будет просто AV в реализации кучи, пытаясь использовать недопустимый указатель.)

Так что Pageheap не дает вам 100% гарантии, чтобы пойматькоррупция именно в тот момент, когда она происходит.Вам нужны такие инструменты, как Purify или Valgrind , которые отслеживают каждый доступ к памяти.

Не поймите меня неправильно, я думаю Pageheap все еще оченьполезно.Это вызывает гораздо меньшее снижение производительности по сравнению с упомянутыми Purify и Valgrind , поэтому позволяет запускать гораздо более сложные сценарии.

...