I'm trying to find a memory leak in a windows MFC 8.0 application (Release build).
After failing to show the full stack trace of allocations using WinDbg (or umdh) due to VC8 CRT's malloc problem with FPO, I've tried to apply the solution proposed here (i.e. using LeakDiag with DbgHlp StackWalk enabled) only to realize that LeakDiag does NOT generate a log file when monitoring the C Runtime Allocator, however, when monitoring the Windows Heap Allocator it does work, but again, the stack trace ends at the malloc call.
Symbols are correctly configured, as I can see function names, filenames, lines, etc. in the file generated.
Does anyone know why I can't log the C Runtime Allocator? and why I can't get a full stack trace even if I'm using the DbgHlp StackWalk API?
I'll appreciate any hint you can provide.
How my stack traces look like:
I've got this using WinDbg. The address is one reported by !heap -l as a leaked block.
0:000> !heap -p -a 25b18400 address 25b18400 found in _HEAP @ 2a70000 HEAP_ENTRY Size Prev Flags UserPtr UserSize - state 25b183f8 0008 0000  25b18400 00021 - (busy) Trace: 00a4 7c97d6dc ntdll!RtlDebugAllocateHeap+0x000000e1 7c959d18 ntdll!RtlAllocateHeapSlowly+0x00000044 7c92b298 ntdll!RtlAllocateHeap+0x00000e64 78134d83 MSVCR80!malloc+0x0000007a
Does anyone know why I can't log the C Runtime Allocator?
You're using a Debug build? The Debug CRT has it's own heap checking that defeats the UMDH and other tools that operate on the global OS heap. Make sure all the MFC and MSVCRT heap debugging features are off when using UMDH and friends.
Perhaps also you, or something in your process, changed the small-block allocator threshold from the default of 0.
Otherwise, the 8.0 release CRT should just forward requests to the global heap, which is what you want for heap debugging tools.
and why I can't get a full stack trace even if I'm using the DbgHlp StackWalk API?
I think Skywing described the details pretty well in the links you gave. Just to re-iterate, the part he perhaps under-stated a bit is "on x86, 'perfect' stack traces are not generally possible, as there is no metadata attached with a particular function (outside of debug symbols) that describes how to unwind past it.". It's quite impractical for DbgHlp to unwind past a function (like MSVCRT's malloc) using EBP as a scratch register.
You could of course re-build your own CRT lib from corrected sources, or try to replace the CRT malloc/free.
Really I think your best move would be to reproduce the leak on an x64 platform, where stack unwinding is guaranteed to be quite reliable.
Why dont you use third party tools?
I.e. download a evaluation copy of intel parallel inspector. Its quite simply installed and run against a existing release build. And it shows - in most cases - a complete stack (i am pretty sure though that it also finds some false positives).
Choose the release version from the configuration manager and make sure it creates a pdb-file (in the linker options). Then just start "Inspect Memory errors".
A number of other comparable tools exist: AQTime, GlowCode. All of these do not require recompilation or instrumentation.
User contributions licensed under CC BY-SA 3.0