Tips to find memory leak from memory dump file.

Hey,

So my task is to find a memory leak in a program and I'm curious if there are any good new tips out there you guys can give me to find a memory leak by reading the memory dump and good ways to find it. So far i rarely had to deal with leaks, because my own software nearly never had mem leaks, but now on a legacy code base i have to deal with them.

I'm interested in how you guys would investigate such a leak :)

For example my dump file looks like this:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 DEFINES:
  _WINPC
  _DEBUG
  _NUGAMEOPTIONS_ENABLE

  FLAGS: 0x0000000f
  FLAGS_DEBUG_CLEAR_ALLOCATED_MEMORY
  FLAGS_DEBUG_CLEAR_FREE_MEMORY
  FLAGS_DEBUG_BLOCK_HEADERS
  FLAGS_DEBUG_BLOCK_HEADERS_EX

  CONTEXT STACK:
  [0x02] = "4WakandaMine_AREA"
  [0x01] = "Game"
  [0x00] = "Initial State"

  PAGES:
  ADDR = 0x0000021B9DAA0000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021B6ABD0000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021B62C90000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021B5EC90000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021AE2DB0000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021B55CC0000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021B4CD50000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021B3A5D0000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021B2A690000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021B256C0000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021B196E0000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021B0D1D0000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021AEF1B0000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021AEB1B0000, SIZE (BYTES) = 67108864     
  ADDR = 0x0000021ABF1B0000, SIZE (BYTES) = 67125856     
  ADDR = 0x0000021AAF1A0000, SIZE (BYTES) = 268452448    
  ADDR = 0x0000021AA8F90000, SIZE (BYTES) = 67108864     

  REFERENCE ADDRESS:
  [NuMain] = 0x00007FF69176F98A

  STATE:
  FREE MEMORY (BYTES) = 588354752    
  ALLOCATED MEMORY (BYTES) = 752869016    
  MINUMUM FREE MEMORY (BYTES) = 270744       
  FREE FRAGMENTS = 3332         
  MAXIMUM FREE FRAGMENTS = 18568        
  LARGEST FREE FRAGMENT SIZE (BYTES) = 67108496     

--------------------------------------------------------------------------------------------------------------------
  BLOCKS FOR CONTEXT "Stranded"
--------------------------------------------------------------------------------------------------------------------
  PRI , ADDRESS            , COUNT      , TOTAL         , ASCRL , CATEGORY  , DEBUG NAME [DATA]
--------------------------------------------------------------------------------------------------------------------
    0 , 0x0000021B6E6348B0 ,          1 ,            72 , ----- , NONE      , NuEastl.h:38 [00 00 00 00 00 00 00 00 ...]
      ,                    ,            ,               ,       ,           ,   [0x00007FF6920CE9CF] NuMemoryManager::_TryBlockAlloc
      ,                    ,            ,               ,       ,           ,   [0x00007FF6920CFA7A] NuMemoryManager::_BlockAlloc
      ,                    ,            ,               ,       ,           ,   [0x00007FF692080DCC] eastl::allocator::allocate
      ,                    ,            ,               ,       ,           ,   [0x00007FF691ECEDC7] eastl::allocate_memory<eastl::allocator>
      ,                    ,            ,               ,       ,           ,   [0x00007FF6936B3E1D] eastl::rbtree<PrioritisedManagerKey,eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64>,eastl::less<PrioritisedManagerKey const >,eastl::allocator,eastl::use_first<eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64> >,1,1>::DoAllocateNode
      ,                    ,            ,               ,       ,           ,   [0x00007FF6936B3F8E] eastl::rbtree<PrioritisedManagerKey,eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64>,eastl::less<PrioritisedManagerKey const >,eastl::allocator,eastl::use_first<eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64> >,1,1>::DoCreateNode
      ,                    ,            ,               ,       ,           ,   [0x00007FF693683984] eastl::rbtree<PrioritisedManagerKey,eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64>,eastl::less<PrioritisedManagerKey const >,eastl::allocator,eastl::use_first<eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64> >,1,1>::DoInsertValueImpl<eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64> >
      ,                    ,            ,               ,       ,           ,   [0x00007FF693682374] eastl::rbtree<PrioritisedManagerKey,eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64>,eastl::less<PrioritisedManagerKey const >,eastl::allocator,eastl::use_first<eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64> >,1,1>::DoInsertValue<eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64> >
      ,                    ,            ,               ,       ,           ,   [0x00007FF693687F77] eastl::rbtree<PrioritisedManagerKey,eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64>,eastl::less<PrioritisedManagerKey const >,eastl::allocator,eastl::use_first<eastl::pair<PrioritisedManagerKey const ,PrioritisedManager * __ptr64> >,1,1>::insert<eastl::pair<PrioritisedManagerKey,PrioritisedManager * __ptr64> >
      ,                    ,            ,               ,       ,           ,   [0x00007FF6936BCEE6] NuMap<PrioritisedManagerKey,PrioritisedManager * __ptr64,eastl::allocator>::Insert
      ,                    ,            ,               ,       ,           ,   [0x00007FF6935EB0C3] PrioritisedManagerList::InsertOrdered
      ,                    ,            ,               ,       ,           ,   [0x00007FF693642CDB] LevelContainer::SetManager
      ,                    ,            ,               ,       ,           ,   [0x00007FF6935EBBF6] ClassManager::SetInContainer
      ,                    ,            ,               ,       ,           ,   [0x00007FF6934E3068] DynamicLightDescManager::DynamicLightDescManager
      ,                    ,            ,               ,       ,           ,   [0x00007FF69351F15D] CreateDynamicLightDescManager
      ,                    ,            ,               ,       ,           ,   [0x00007FF6935EBF13] ClassManager::CreateManager
      ,                    ,            ,               ,       ,           ,   
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
    1 , 0x0000021B2C3B5FD8 ,          1 ,            64 ,
      ,                    ,            ,               ,       ,           ,   [0x00007FF6920CE9CF] NuMemoryManager::_TryBlockAlloc
      ,                    ,            ,               ,       ,           ,   [0x00007FF6920CFA7A] NuMemoryManager::_BlockAlloc
      ,                    ,            ,               ,       ,           ,   [0x00007FF692112DD6] IEventListener::SubscribedEvent::Create
      ,                    ,            ,               ,       ,           ,   [0x00007FF692112F81] IEventListener::AddSubscribedEvent
      ,                    ,            ,               ,       ,           ,   [0x00007FF69211368E] Event::Subscribe
      ,                    ,            ,               ,       ,           ,   [0x00007FF6934D8320] DynamicLightManager::DynamicLightManager
      ,                    ,            ,               ,       ,           ,   [0x00007FF69351F0DD] CreateDynamicLightManager
      ,                    ,            ,               ,       ,           ,   [0x00007FF6935EBF13] ClassManager::CreateManager
      ,                    ,            ,               ,       ,           ,   [0x00007FF6923017F4] EdClassHelperT<PlaceableInterface,PlaceableBase,PlaceableAccessor>::CreateObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF693DF10CF] ApiClassInterface::CreateObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF693DF0FF6] ApiClassInterface::CreateObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF693E012C2] ApiClass::CreateObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF693DFCD13] ApiClass::CreateAndLinkClassObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF691FC6AF0] ApiClass::CreateAndLinkClassObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF6972CF119] PlaceableBase::CloneObjectTree
      ,                    ,            ,               ,       ,           ,   [0x00007FF6972CF76B] PlaceableBase::CloneObjectTree
      ,                    ,            ,               ,       ,           ,   [0x00007FF6972CBFC9] PlaceableBase::Clone
      ,                    ,            ,               ,       ,           ,   [0x00007FF6934B16B6] VfxManager::Trigger
      ,                    ,            ,               ,       ,           ,   [0x00007FF6934B1B15] VfxManager::TriggerLooping
      ,                    ,            ,               ,       ,           ,   [0x00007FF6934AC29C] VfxManager::CreateInstance
      ,                    ,            ,               ,       ,           ,   [0x00007FF693440BDD] EffectManager::CreateInstance
      ,                    ,            ,               ,       ,           ,   [0x00007FF692F5FCEF] VfxHolder::Process
      ,                    ,            ,               ,       ,           ,   [0x00007FF692F64156] VfxHolderManager::OnProcess
      ,                    ,            ,               ,       ,           ,   [0x00007FF693644D3F] LevelContainerManager::Process
      ,                    ,            ,               ,       ,           ,   [0x00007FF69364D397] GameFramework::Process
      ,                    ,            ,               ,       ,           ,   [0x00007FF693650F42] GameFramework::Run
      ,                    ,            ,               ,       ,           ,   [0x00007FF6935EAEDE] NuMain
      ,                    ,            ,               ,       ,           ,   [0x00007FF698513FA9] main
      ,                    ,            ,               ,       ,           ,   pointed at by --> nuapievent.cpp:689 0x0000021B56FB9C98
    1 , 0x0000021B198C1A88 ,          1 ,            64 , ----- , NONE      , nuapievent.cpp:689 [30 24 93 E6 1A 02 00 00 ...]
      ,                    ,            ,               ,       ,           ,   [0x00007FF6920CE9CF] NuMemoryManager::_TryBlockAlloc
      ,                    ,            ,               ,       ,           ,   [0x00007FF6920CFA7A] NuMemoryManager::_BlockAlloc
      ,                    ,            ,               ,       ,           ,   [0x00007FF692112DD6] IEventListener::SubscribedEvent::Create
      ,                    ,            ,               ,       ,           ,   [0x00007FF692112F81] IEventListener::AddSubscribedEvent
      ,                    ,            ,               ,       ,           ,   [0x00007FF69211368E] Event::Subscribe
      ,                    ,            ,               ,       ,           ,   [0x00007FF6934D833A] DynamicLightManager::DynamicLightManager
      ,                    ,            ,               ,       ,           ,   [0x00007FF69351F0DD] CreateDynamicLightManager
      ,                    ,            ,               ,       ,           ,   [0x00007FF6935EBF13] ClassManager::CreateManager
      ,                    ,            ,               ,       ,           ,   [0x00007FF6923017F4] EdClassHelperT<PlaceableInterface,PlaceableBase,PlaceableAccessor>::CreateObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF693DF10CF] ApiClassInterface::CreateObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF693DF0FF6] ApiClassInterface::CreateObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF693E012C2] ApiClass::CreateObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF693DFCD13] ApiClass::CreateAndLinkClassObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF691FC6AF0] ApiClass::CreateAndLinkClassObject
      ,                    ,            ,               ,       ,           ,   [0x00007FF6972CF119] PlaceableBase::CloneObjectTree
      ,                    ,            ,               ,       ,           ,   [0x00007FF6972CF76B] PlaceableBase::CloneObjectTree
      ,                    ,            ,               ,       ,           ,   [0x00007FF6972CBFC9] PlaceableBase::Clone
      ,                    ,            ,               ,       ,           ,   [0x00007FF6934B16B6] VfxManager::Trigger
      ,                    ,            ,               ,       ,           ,   [0x00007FF6934B1B15] VfxManager::TriggerLooping
      ,                    ,            ,               ,       ,           ,   [0x00007FF6934AC29C] VfxManager::CreateInstance
      ,                    ,            ,               ,       ,           ,   [0x00007FF693440BDD] EffectManager::CreateInstance
      ,                    ,            ,               ,       ,           ,   [0x00007FF692F5FCEF] VfxHolder::Process
      ,                    ,            ,               ,       ,           ,   [0x00007FF692F64156] VfxHolderManager::OnProcess
      ,                    ,            ,               ,       ,           ,   [0x00007FF693644D3F] LevelContainerManager::Process
      ,                    ,            ,               ,       ,           ,   [0x00007FF69364D397] GameFramework::Process
      ,                    ,            ,               ,       ,           ,   [0x00007FF693650F42] GameFramework::Run
      ,                    ,            ,               ,       ,           ,   [0x00007FF6935EAEDE] NuMain
      ,                    ,            ,               ,       ,           ,   [0x00007FF698513FA9] main
      ,                    ,            ,               ,       ,           ,   pointed at by --> nuapievent.cpp:689 0x0000021B2C3B5FD8
Is a dump all you have to work with? There are several leak detection libraries, but they require recompiling the binary.
well i also have Visual Studio :P

As far as i know the dump provides all the leaking memory adresses, and their call stack of creation. but not sure whats the best way / steps to fix the leak.

I found one of the addresses in the program and checking the way it is created at the moment.
I've found the leak already.

The way i did it now was to go to the VFXManager(a class listed in the mem dump) for example and print out the address of the created instance, and check if it is in the mem dump.

Once I found the leaking memory address it was kinda easy to find the problem.

But would be still great to get some tips for future leaks :)

And for other checking I just cast the addresses to one of the Listed Classes in the VS watch window and check for any usable information
Last edited on
Best way to avoid memory leaks is not to use dynamic memory unless you really, really have to.
In C++ you can use the stl containers, which manage their own memory, or if you really need a pointer then use a smart pointer.
the old school solution is called "discipline" or maybe 'defensive coding'.
if you invoke a 'new' statement, you immediately stop what you are doing and ask yourself where the delete will go. Put it there right now. In 'real' code I do the same with brackets {} or () or the like ... if I type { I immediately type } and back up to fill in between, and if nested I comment end of brackets with the statement they close:

1
2
3
4
5
6
7
if(blah)
{
   if(foo)
   {
      ;
   }//if(foo)
}//if(blah) 


this isnt foolproof, of course, but it reduces the problem. You can always have branches that manage to bypass a delete somehow or objects / routines that leak via a class member.
Last edited on
At risk of Holy War time, by using a smart pointer, the delete has been placed exactly where it needs to be, always and forever, even if the code changes in the future (within reason; a suitable motivated coder can always screw things up). I certainly agree with the need to discipline yourself, but it's the discipline to use a smart pointer or other such RAII method that simply isn't exposed to as many bugs and problems as new/delete.
Last edited on
I agree, but many posters here are in school and forced to use various constructs or denied access to some advanced tools. If being forced to use new/delete or working with legacy code or something off the web, there are merits to knowing the old school way. If able to write freely, use the tools we have for sure.

and there are no smart brackets (though some IDEs have a match indication).
Last edited on
I have to say, I don't think I've ever encountered a bug caused by misplaced braces. I have encountered failed compilations, but that's hardly critical.
I'm not saying bugs of this kind can't happen, I'm saying that I've never needed to be particularly mindful to avoid such bugs.
I agree, but many posters here are in school and forced to use various constructs or denied access to some advanced tools.


Yes, seguing off topic, that's another personal trigger for me :) As far as I'm concerned, new/delete and arrays and c-style strings (amongst other things) are advanced topics. They don't work how beginners expect, they're more difficult to understand than simpler alternatives that do work how beginners expect, and to use them safely requires knowledge the inexperienced struggle to build a mental model with.
"Why I use new/delete?": the reason is i'm working in a team with an large in house game engine which contains legacy code, the memory is actually not leaking, but kinda stranded, it get cleaned up at sum point by some kind of custom "GC".

Topic archived. No new replies allowed.