PageHeap не показывает точное место сбоя

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

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


person Maanu    schedule 08.05.2011    source источник
comment
что заставило вас думать, что у вас есть повреждение кучи? Если включение кучи страниц не привело к сбою в том месте, где, как вы подозреваете, куча была повреждена, возможно, у вас другая проблема. Используете ли вы catch(...) в своем приложении, это фактически улавливает нарушения прав доступа, поэтому ваше приложение не будет аварийно завершать работу в этом месте. После включения кучи страниц вы использовали отладчик для запуска приложения? (VS в среде разработки или adplus в производственной среде)   -  person DXM    schedule 08.05.2011
comment
@DXM: я начал часто сталкиваться с проблемой после включения опции /RTCs. Я отключил все ctach(...). Я использую среду разработки VS для отладки.   -  person Maanu    schedule 08.05.2011


Ответы (2)


Включение FULL pageheap может увеличить шансы того, что отладчик поймает повреждение кучи, когда это происходит:

gflags /p /enable /full <processname>

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

person pepsi    schedule 20.07.2011

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, поэтому позволяет запускать гораздо более сложные сценарии.

person glagolig    schedule 07.09.2013