Investigating Memory Leak

4

We have a slow memory leak in our application and I've already gone through the following steps in trying to analyize the cause for the leak:

  1. Enabling user mode stack trace database in GFlags
  2. In Windbg, typing the following command: !heap -stat -h 1250000 (where 1250000 is the address of the heap that has the leak) After comparing multiple dumps, I see that a memory blocks of size 0xC are increasing over time and are probably the memory that is leaked.
  3. typing the following command: !heap -flt s c gives the UserPtr of those allocations and finally:
  4. typing !heap -p -a address on some of those addresses always shows the following allocation call stack:

0:000> !heap -p -a 10576ef8

address 10576ef8 found in
_HEAP @ 1250000
  HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
    10576ed0 000a 0000  [03]   10576ef8    0000c - (busy)
    mscoreei!CLRRuntimeInfoImpl::`vftable'
    7c94b244 ntdll!RtlAllocateHeapSlowly+0x00000044
    7c919c0c ntdll!RtlAllocateHeap+0x00000e64
    603b14a4 mscoreei!UtilExecutionEngine::ClrHeapAlloc+0x00000014
    603b14cb mscoreei!ClrHeapAlloc+0x00000023
    603b14f7 mscoreei!ClrAllocInProcessHeapBootstrap+0x0000002e
    603b1614 mscoreei!operator new[]+0x0000002b
    603d402b +0x0000005f
    603d5142 mscoreei!GetThunkUseState+0x00000025
    603d6fe8 mscoreei!_CorDllMain+0x00000056
    79015012 mscoree!ShellShim__CorDllMain+0x000000ad
    7c90118a ntdll!LdrpCallInitRoutine+0x00000014
    7c919a6d ntdll!LdrpInitializeThread+0x000000c0
    7c9198e6 ntdll!_LdrpInitialize+0x00000219
    7c90e457 ntdll!KiUserApcDispatcher+0x00000007

This looks like thread initialization call stack but I need to know more than this. What is the next step you would recommend to do in order to put the finger at the exact cause for the leak.

windows
debugging
memory-management
memory-leaks
windbg
asked on Stack Overflow Apr 5, 2012 by galbarm • edited Apr 5, 2012 by galbarm

2 Answers

6

The stack recorded when using GFlags is done without utilizing .pdb and often not correct. Since you have traced the leak down to a specific size on a given heap, you can try to set a live break in RtlAllocateHeap and inspect the stack in windbg with proper symbols. I have used the following with some success. You must edit it to suit your heap and size.

 $$ Display stack if heap handle eq 0x00310000 and size is  0x1303
 $$ ====================================================================
bp ntdll!RtlAllocateHeap "j ((poi(@esp+4) = 0x00310000) & (poi(@esp+c) = 0x1303) )'k';'gc'" 

Maybe you then get another stack and other ideas for the offender.

answered on Stack Overflow Apr 10, 2012 by Kjell Gunnar • edited May 9, 2015 by Kjell Gunnar
2

The first thing is that the new operator is the new [] operator so is there a corresponding delete[] call and not a plain old delete call?

If you suspect this code I would put a test harness around it, for instance put it in a loop and execute it 100 or 1000 times, does it still leak and proportionally.

You can also measure the memory increase using process explorer or programmatically using GetProcessInformation.

The other obvious thing is to see what happens when you comment out this function call, does the memory leak go away? You may need to do a binary chop if possible of the code to reduce the likely suspect code by half (roughly) each time by commenting out code, however, changing the behaviour of the code may cause more problems or dependant code path issues which can cause memory leaks or strange behaviour.

EDIT Ignore the following seeing as you are working in a managed environment.

You may also consider using the STL or better yet boost reference counted pointers like shared_ptr or scoped_array for array structures to manage the lifetime of the objects.

answered on Stack Overflow Apr 5, 2012 by EdChum • edited Apr 6, 2012 by EdChum

User contributions licensed under CC BY-SA 3.0