В настоящее время я пытаюсь отследить источник повреждения кучи в нашей кодовой базе, которая не отображается, когда включено отслеживание кучи полной страницы (поэтому только обычное отслеживание страницы).
IЯ использую Application Verifier для устранения повреждения и получения не очень полезного кода остановки 00000008:
APPLICATION_VERIFIER_HEAPS_CORRUPTED_HEAP_BLOCK (8)
Поврежденный блок кучи.
Это блокгенерируется общая ошибка, если повреждение в блоке кучи нельзя поместить в более конкретную категорию.
======================================
ОСТАНОВКА ПРОВЕРКИ 00000008: pid 0xD30: поврежденный блок кучи.
00000000: дескриптор кучи, используемый в вызове.
0861C000: блок кучиучаствует в операции.
0000043C: размер блока кучи.
00000000: зарезервирован
=============================================
Мне пришлось сократить отчет, чтобы защитить невинных, но потерпите меня.В стеке вызовов показано:
1000c540 00000008 00000000 vrfcore!VerifierStopMessageEx+0x543
00000008 7c969624 00000000 vrfcore!VfCoreRedirectedStopMessage+0x81
00000000 00000009 0861c000 ntdll!RtlpDphReportCorruptedBlock+0x101
04a680ee 01001002 03ce1000 ntdll!RtlpDphTrimDelayedFreeQueue+0x84
03ce1000 01001002 04a680ee ntdll!RtlpDphNormalHeapFree+0xc0
03ce0000 01001002 137a0040 ntdll!RtlpDebugPageHeapFree+0x79
03ce0000 01001002 137a0040 ntdll!RtlDebugFreeHeap+0x2c
03ce0000 01001002 137a0040 ntdll!RtlFreeHeapSlowly+0x37
03ce0000 00000000 137a0040 ntdll!RtlFreeHeap+0xf9
137a0040 137a0040 030dfe61 msvcrt!free+0xc3
Первоначально я сосредоточил свое внимание на вызове free()
, предполагая, что память, которую я пытался освободить, была виновником повреждения кучи.Это все еще может иметь место, но я больше не убежден.Наблюдая за 0x137a0040
, пока я выполняю вызов удаления, кажется, память освобождается при вызове RtlpDphNormalHeapFree()
.Я предполагаю, что она освобождается должным образом, поскольку память от 0x137a0040
до ее верхней границы примерно через 76 МБ состоит исключительно из f0
, определяемой здесь как свободная память.
Поэтому мое внимание переключается на вызов непосредственно перед вызовом на RtlpDphReportCorruptedBlock()
, RtlpDphTrimDelayedFreeQueue()
.Аргументы, переданные в RtlpDphReportCorruptedBlock()
, указали бы мне (только предположение, я не могу найти никаких подсказок относительно объявлений этих функций), что это поврежденный блок.Исследование этого блока показывает следующее:
0861c000 f0 f0 f0 f0 4f f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 ....O..............
Почему этот 5-й байт 4f
, а все остальные f0
(уже освобождены)?Что делает RtlpDphTrimDelayedFreeQueue()
?Является ли проблемой (если это проблема) то, что эта функция пытается освободить то, что явно уже освободило память, или эта функция ожидает, что эта память уже свободна, и теряет график, когда встречает этот 5-й байт?
(5-й байт является единственным нечетным, 0x0861c000
до 0x0861c43c
равен f0
)
К сожалению, хотя я могу воспроизвести повреждение кучи в 100% случаев, адрескажется, меняется каждый раз, когда я помещаю на него точку останова данных.
Я работаю на Windows XP SP3, и приложение написано на VC ++ 6
Есть идеи?