Heap corruption error.
- From: s.k.easley@xxxxxxxxx
- Date: 14 Mar 2007 17:03:20 -0700
Hi all,
I'm battling a heap corruption error. I know you're probably thinking
it's either a buffer overrun or writing to a freed block. I've gone
after enough of these to know that's what it usually is, and I know
how to find and fix such errors. However this one appears to be
different, and I'll explain why.
First of all, I'm using MS Visual Studio 6.0.
When the error manifests, the debug heap's linked list of allocated
objects is corrupted. More specifically, following the block's
pBlockHeaderNext pointers quickly takes me to heap memory that is not
a block. I can often, but not always, find the block close to where
the pointer says it should be. I know it's the next block because its
pBlockHeaderPrev pointer points to the block I just came from.
Sometimes its 8 or 16 bytes away. Usually more. Occasionally I can't
find it at all.
The pBlockHeaderNext pointer looks valid in that it's most significant
byte is 04, like all of my heap's blocks, and the least significant
byte is 00 or 08, since the heap blocks are on 8 byte boundaries. So
the pointer looks valid, it just doesn't point to anything
recognizable as a block.
In the cases where I could find the next block, in all but one case
the pBlockHeaderPrev links were fine. So following the linked list
from most recent allocation back was broken, but following the list
from earliest allocation forward was fine. In the one case where the
pBlockHeaderPrev wasn't fine, I found the Prev pointer in the middle
of another block (corrupting it, of course).
I've also had one case where the head of the linked list,
_pFirstBlock, pointed into the heap, but not at a block. I'm guessing
that the program was freeing the last allocated block, and that
block's pBlockHeaderNext was already spurious, and the free operation
copied the block's spurious pBlockHeaderNext to pFirstBlock.
So I don't think it's a buffer overrun because:
a) If the block containing the pBlockHeaderNext was overrun onto, that
block should look trashed. There's very little chance the
pBlockHeaderNext pointer would still look like a valid heap pointer.
Even if just the first byte of that block was overwritten (the Next
pointer's LSB), it would be have to be changing a 00 to a 08 or visa-
versa to cause a problem and still look like a valid heap pointer.
b) If the next block were overrun so that it was no longer
recognizable as a block, I would never be able to find the block
elsewhere in the heap.
c) I haven't found a block yet that had its no-mans-land bytes
overwritten. I've gotten pretty good at spotting no-mans-land bytes,
and using them to find the start and end of blocks.
It may be a write-after-free, in which the freed area has been
reallocated and the write is corrupting the linked list. Again, I
think that it would be extremely unlikely that writing over the
pBlockHeaderPrev would result in something that still looks like a
valid heap pointer. Also, I've tried setting the
_CRTDBG_DELAY_FREE_MEM_DF flag. This causes the bug to stop
manifesting, and ASSERT(AfxCheckMemory()), which should be checking to
make sure the freed blocks contain 0xdd, never trips.
So this is looking like a type of heap corruption that I've not seen
before. It almost looks like a concurrency issue in which an
allocation and free or two frees occur in different threads corrupting
the updating of the linked list pointers. However, my application and
all of my libraries are using the Multithreaded Debug DLL, so allocs
and frees should be protected from concurrent access.
If you have any insight into this, or any suggestions, or if you can
find any holes in my logic. please let me know.
Thanks in advance.
.
- Prev by Date: Re: Subclass hiding method problem.
- Next by Date: Re: Control another program
- Previous by thread: SetMenuItemBitmaps
- Next by thread: To Load a Bitmap on the CStatic Control
- Index(es):
Relevant Pages
|