When battling memory leaks, you often start from the output of _CrtMemDumpAllObjectsSince or _CrtDumpMemoryLeaks (called for you if you use MFC) – something similar to:
C:\myfile.cpp(20): {130} normal block at 0x00780E80, 68 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
I’ve mentioned a way to break at the 130th allocation by setting _crtBreakAlloc to 130 (either by _CrtSetBreakAlloc or from the debugger). Unfortunately this works only if the allocation number is consistent across runs – and this is not the case when the code contains threaded regions (with allocations) up to the leaking allocation.
As an alternative, here’s another trick that works very well for me: the allocated sizes are virtually always consistent across runs. They are not guaranteed to be unique, of course, but you can often notice at least one seemingly non-random requested size – notice the bold 68 at the dump above. Once you do, all that remains is to set a breakpoint at _heap_alloc_dbg, and set a condition on it:
nSize == RequestedAllocSizeToTrack .
A glimpse at the code might help:
There is no direct CRT API for this, but the hassle is minimal and I prefer anyway to maximize the use of the debugger and avoid recompilation.
I hoped to be able to set the breakpoint from the breakpoints window using the context operator, but I can’t locate _heap_alloc_dbg in msvcrXXd.dll exports. Any advice would be appreciated!
You can try similar tricks with _malloc_dbg (which is visibly exported), but that would probably work only if you’re positive that’s where your allocation are channeled through (and not, e.g., _aligned_malloc_dbg).
I tried your technique just now by putting the conditional breakpoint in dbgheap.c.
Unfortunately, it is too taxing on my system. The software falls behind and causes the hardware to timeout.
I think this works on software that doesn’t have timing requirement. Otherwise, it might not work as well.
Regardless, this is an excellent trick.
Thanks.
… Alan
Alan – thanks. You’re right, of course. A conditional breakpoint is a breakpoint: the debugger halts the process *on every allocation*, evaluates the conditional expression, and resumes execution – it can get *very* slow.
If – unlike me – recompiling is not such a burden to you, there is a much faster alternative. Stay tuned..
Pingback: Tweets that mention Debugging Memory Leaks, Part 3: Breaking on Allocations of Given Size « Ofek's Visual C++ stuff -- Topsy.com