I am currently trying to find the source of heap damage in our code base, which does not appear when full page heap tracking is enabled (so only regular page tracking).
I use Application Verifier to break corruption and get a not very useful stop code 00000008:
APPLICATION_VERIFIER_HEAPS_CORRUPTED_HEAP_BLOCK (8)
Damaged block heap.
This is a common mistake if corruption in the heap block cannot be placed in a more specific category.
=========================================
VERIFIER STOP 00000008: pid 0xD30: heap block is damaged.
00000000: the heap handle used in the call.
0861C000: heap block involved in the operation.
0000043C: Heap block size.
00000000: reserved
=========================================
I had to cut the report to protect the innocent, but carry me. The callstack shows:
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
Now, initially, I focused my attention on calling free() , believing that the memory I was trying to free was the culprit of the heap. It may be so, but I am no longer convinced. By observing 0x137a0040 , when I make a delete call, the memory seems to be correctly freed by calling RtlpDphNormalHeapFree() . I summarize that it is correctly freed, since the memory from 0x137a0040 has an upper bound to it, and the 76mb part later consists only of f0 , which is defined here as free memory.
Therefore, my attention is drawn to the call immediately before the call to RtlpDphReportCorruptedBlock() , RtlpDphTrimDelayedFreeQueue() . The arguments passed to RtlpDphReportCorruptedBlock() would tell me (just the assumption that I cannot find any hints of declarations of these functions) to be a damaged block. Examination of this block displays the following:
0861c000 f0 f0 f0 f0 4f f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 ....O..............
Why is this 5th byte 4f , and all the rest f0 (already freed)? What does RtlpDphTrimDelayedFreeQueue() do? Is the problem (if it is a problem) that this function is trying to free something that has explicitly freed memory, or does this function expect this memory to already be free and lose its plot when it encounters this 5th byte?
(The fifth byte is the only odd, 0x0861c000 - 0x0861c43c - f0 )
Unfortunately, although I can reproduce a bunch of corruption in 100% of cases, the address seems to change every time I put a data breakpoint on it.
I work on Windows XP SP3 and the application is written in VC ++ 6
Any ideas?