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