Rooting out a memory leak with tools

Started by
5 comments, last by sipickles 16 years, 11 months ago
Hi, After solving a directX memory leak leak I had, I found one in my c++ (using MSVC2005 Express). I've added these helpers:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

This give me this output:

Detected memory leaks!
Dumping objects ->
{51031} normal block at 0x01E88C38, 496 bytes long.
 Data: <      zC  zD ->C> 00 00 00 00 00 00 7A 43 00 00 7A 44 E3 2D 3E 43 
{51030} normal block at 0x01E88A08, 496 bytes long.
 Data: <      zC  zD=y ?> 00 00 00 00 00 00 7A 43 00 00 7A 44 3D 79 13 3F 
Object dump complete.
The thread 'Win32 Thread' (0xeb0) has exited with code 0 (0x0).
The program '[4000] water 20070511.exe: Native' has exited with code 0 (0x0).

Then, I used Visual Leak Detector to provide some more info, and got this:

The thread 'Win32 Thread' (0x330) has exited with code 0 (0x0).
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 26416 at 0x02E08A08: 496 bytes ----------
  Call Stack:
    m:\_dev\water 20070511\simulation\water\cwatersurface.cpp (272): CWaterSurface::Prepare
    m:\_dev\water 20070511\simulation\water\cwatermanager.cpp (182): CWaterManager::Update
    m:\_dev\water 20070511\simulation\csimulationlayer.cpp (341): cSimulationLayer::Update
    f:\_dev\water 20070511\client.cpp (75): Update
    m:\_dev\water 20070511\framework\cframework.cpp (567): cFramework::Loop
    m:\_dev\water 20070511\framework\cframework.cpp (521): cFramework::MsgProc
    m:\_dev\water 20070511\framework\cframework.cpp (54): WinMain
    f:\sp\vctools\crt_bld\self_x86\crt\src\crtexe.c (589): __tmainCRTStartup
    f:\sp\vctools\crt_bld\self_x86\crt\src\crtexe.c (414): WinMainCRTStartup
    0x7C816FD7 (File and line number not available): RegisterWaitForInputIdle
  Data:
    00 00 00 00    00 00 7A 43    00 00 7A 44    BC C3 DB 3E     ......zC ..zD...>
    CC 60 78 BE    72 B9 5E BF    F1 C8 DB 3D    EA 5A 78 3F     .`x.r.^. ...=.Zx?
    B9 BE 5E BE    8F 94 65 BF    00 00 00 00    86 87 E2 BE     ..^...e. ........
    00 00 34 42    71 3D AA 3F    00 00 48 42    00 C8 AF 47     ..4Bq=.? ..HB...G
    67 E1 7A BE    EF 64 66 40    00 00 00 00    CD CD CD CD     g.z..df@ ........
    8E 94 65 BF    F1 C8 DB 3D    BC C3 DB 3E    00 00 00 00     ..e....= ...>....
    00 00 00 00    EA 5A 78 3F    CD 60 78 BE    00 00 00 00     .....Zx? .`x.....
    85 87 E2 BE    B9 BE 5E BE    72 B9 5E BF    00 00 00 00     ......^. r.^.....
    58 38 DD 43    40 14 C8 C1    02 AA 68 44    00 00 80 3F     X8.C@... ..hD...?
    8F 94 65 BF    00 00 00 80    86 87 E2 BE    00 00 00 80     ..e..... ........
    F1 C8 DB 3D    EA 5A 78 3F    B9 BE 5E BE    00 00 00 80     ...=.Zx? ..^.....
    BC C3 DB 3E    CC 60 78 BE    72 B9 5E BF    00 00 00 80     ...>.`x. r.^.....
    00 00 00 B8    00 00 7A 43    02 00 7A 44    01 00 80 3F     ......zC ..zD...?
    21 85 AC 3F    00 00 00 00    00 00 00 00    00 00 00 00     !..?.... ........
    00 00 00 00    A0 73 E5 3F    00 00 00 00    00 00 00 00     .....s.? ........
    00 00 00 00    00 00 00 00    37 12 80 3F    00 00 80 3F     ........ 7..?...?
    00 00 00 00    00 00 00 00    76 1C 48 C2    00 00 00 00     ........ v.H.....
    F6 EF 3D 3F    00 00 00 80    00 00 00 00    00 00 00 80     ..=?.... ........
    00 00 00 80    5E CF 0E 3F    00 00 00 80    00 00 00 00     ....^..? ........
    00 00 00 00    00 00 00 80    00 00 00 00    BC BF A3 BC     ........ ........
    00 00 00 80    00 00 00 00    FF FF 7F 3F    0A D7 A3 3C     ........ ...?...<
    33 B7 9A BF    04 FE 44 3E    02 E3 DB 3E    BC C3 DB 3E     3.....D> ...>...>
    00 00 00 00    7F 99 DE 3F    25 84 78 BE    CD 60 78 BE     .......? %.x..`x.
    DB A8 18 BF    36 A5 C7 BE    24 D9 5E BF    72 B9 5E BF     ....6... $.^.r.^.
    E6 14 15 44    7B 54 33 C2    57 49 5C 44    02 AA 68 44     ...D{T3. WI\D..hD
    E1 55 2A BF    DA 6F 29 33    61 12 A8 BE    6A 9C D0 2D     .U*..o)3 a...j..-
    09 37 75 3D    9C 8B 0A 3F    6A 84 F8 BD    42 D7 23 2F     .7u=...? j...B.#/
    AE 8C 07 35    45 E9 9F C0    44 E9 9F C1    C2 BF A3 BC     ...5E... D.......
    AC C3 DB 3E    00 3D 98 40    39 0A 99 41    11 D7 A3 3C     ...>.=.@ 9..A...<
    00 00 00 00    CD CD CD CD    00 CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    00 00 00 00    0F 00 00 00     ........ ........

---------- Block 26417 at 0x02E08C38: 496 bytes ----------
  Call Stack:
    m:\_dev\water 20070511\simulation\water\cwatersurface.cpp (522): CWaterSurface::GetMinMax
    m:\_dev\water 20070511\simulation\water\cwatersurface.cpp (275): CWaterSurface::Prepare
    m:\_dev\water 20070511\simulation\water\cwatermanager.cpp (182): CWaterManager::Update
    m:\_dev\water 20070511\simulation\csimulationlayer.cpp (341): cSimulationLayer::Update
    f:\_dev\water 20070511\client.cpp (75): Update
    m:\_dev\water 20070511\framework\cframework.cpp (567): cFramework::Loop
    m:\_dev\water 20070511\framework\cframework.cpp (521): cFramework::MsgProc
    m:\_dev\water 20070511\framework\cframework.cpp (54): WinMain
    f:\sp\vctools\crt_bld\self_x86\crt\src\crtexe.c (589): __tmainCRTStartup
    f:\sp\vctools\crt_bld\self_x86\crt\src\crtexe.c (414): WinMainCRTStartup
    0x7C816FD7 (File and line number not available): RegisterWaitForInputIdle
  Data:
    00 00 00 00    00 00 7A 43    00 00 7A 44    E0 D1 0B 43     ......zC ..zD...C
    00 00 7A C3    40 B3 8D C3    F1 C8 DB 3D    EA 5A 78 3F     ..z.@... ...=.Zx?
    B9 BE 5E BE    56 94 65 BF    00 00 00 00    6C 88 E2 BE     ..^.V.e. ....l...
    00 00 34 42    71 3D AA 3F    00 00 48 42    00 C8 AF 47     ..4Bq=.? ..HB...G
    67 E1 7A BE    EF 64 66 40    00 00 00 00    CD CD CD CD     g.z..df@ ........
    55 94 65 BF    48 8C 8C 3E    35 A9 B1 3E    00 00 00 00     U.e.H..> 5..>....
    00 00 00 00    58 C5 48 3F    8D D4 1E BF    00 00 00 00     ....X.H? ........
    6B 88 E2 BE    2A 70 0E BF    DD 0C 34 BF    00 00 00 00     k...*p.. ..4.....
    38 39 DD 43    B6 2A B4 43    74 9B 56 44    00 00 80 3F     89.C.*.C t.VD...?
    56 94 65 BF    00 00 00 80    6C 88 E2 BE    00 00 00 80     V.e..... l.......
    48 8C 8C 3E    58 C5 48 3F    2A 70 0E BF    00 00 00 80     H..>X.H? *p......
    34 A9 B1 3E    8D D4 1E BF    DC 0C 34 BF    00 00 00 80     4..>.... ..4.....
    00 00 80 37    03 00 7A 43    FE FF 79 44    00 00 80 3F     ...7..zC ..yD...?
    21 85 AC 3F    00 00 00 00    00 00 00 00    00 00 00 00     !..?.... ........
    00 00 00 00    A0 73 E5 3F    00 00 00 00    00 00 00 00     .....s.? ........
    00 00 00 00    00 00 00 00    37 12 80 3F    00 00 80 3F     ........ 7..?...?
    00 00 00 00    00 00 00 00    76 1C 48 C2    00 00 00 00     ........ v.H.....
    F6 EF 3D 3F    00 00 00 80    00 00 00 00    00 00 00 80     ..=?.... ........
    00 00 00 80    5E CF 0E 3F    00 00 00 80    00 00 00 00     ....^..? ........
    00 00 00 00    00 00 00 80    00 00 00 00    BC BF A3 BC     ........ ........
    00 00 00 80    00 00 00 00    FF FF 7F 3F    0A D7 A3 3C     ........ ...?...<
    0D B7 9A BF    EF F1 FB 3E    7D C2 B1 3E    35 A9 B1 3E     .......> }..>5..>
    00 00 00 00    36 F3 B3 3F    27 EB 1E BF    8D D4 1E BF     ....6..? '.......
    76 A9 18 BF    56 55 7F BF    7C 26 34 BF    DD 0C 34 BF     v...VU.. |&4...4.
    7D 15 15 44    95 7B 21 44    37 38 4A 44    74 9B 56 44     }..D.{!D 78JDt.VD
    B5 55 2A BF    AC 8C 87 32    0E 13 A8 BE    00 00 00 80     .U*....2 ........
    4D CF 1C 3E    34 00 E0 3E    2C EB 9E BE    00 00 00 80     M..>4..> ,.......
    00 00 00 00    44 E9 9F C0    42 E9 9F C1    C0 BF A3 BC     ....D... B.......
    3A A9 B1 3E    71 25 8C 40    9D 5F 9A 41    0E D7 A3 3C     :..>q%.@ ._.A...<
    00 00 00 00    CD CD CD CD    00 CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    00 00 00 00    0F 00 00 00     ........ ........

Visual Leak Detector detected 2 memory leaks.
Visual Leak Detector is now exiting.
The program '[1556] water 20070511.exe: Native' has exited with code 0 (0x0).
What could cause memory leaks like this? I am familiar with the concepts in DX9, allocating resources which need to be freed, and new/delete. Having them in less obvious places is new to me!
Advertisement
A rough rule is that any DirectX object created using a function beginning with Create needs to be Released when you're done with it. It's all COM, so be sure that objects are destroyed in reverse order of creation.

free and delete play no role in COM, so you use them only on memory you allocated with malloc and new (respectively) manually. Since we're talking about C++ here, you shouldn't be using malloc (and hence free) at all - new provides all the functionality with added type- and exception-safety.

If in doubt, release any object that offers the method. If you get an exception on execution, then it probably doesn't want to be released.

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Pay attention that also all surfaces acquired by GetSurfaceLevel() or GetCubeMapSurface() need to be released after usage. But these are mistakes that the DX memleak checker should catch as well. DX is not involved in the problem you have posted. What does the allocation VLD points at look like? If it's a simple new, you just have missed to add the appropriate delete.
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.
It doesn't look like a COM leak (AFAIK, these won't show up using the crt debugger anyway). If you want the debugger to point to the statement that lead up to the leak, use _CrtSetBreakAlloc along with the object allocation order number. For example:
Detected memory leaks!Dumping objects ->{51031} normal block at 0x01E88C38, 496 bytes long. Data: <      zC  zD ->C> 00 00 00 00 00 00 7A 43 00 00 7A 44 E3 2D 3E 43 ...Object dump complete.The thread 'Win32 Thread' (0xeb0) has exited with code 0 (0x0).The program '[4000] water 20070511.exe: Native' has exited with code 0 (0x0).


The object allocation order number here equals 51031, so insert the following statement at the beginning of your application:
_CrtSetBreakAlloc( 51031 );

Yeah its not a COM issue, its definately CRT.

Sorry for using the word 'freeing'. I've never used a malloc in my life :)

So _CrtSetBreakAlloc() works well.

It points to a line which says:

delete camera;                    //    This line contains leakprojector = new CCamera( cam );


Any idea why this object would not be deleted entirely? I mean, there are only 496 bytes leaking!

Weird!
Quote:Original post by sipickles

Any idea why this object would not be deleted entirely? I mean, there are only 496 bytes leaking!

Weird!


Is the camera a hierarchy of cameras and therefore is the base destructor virtual and any class which is further derived from?
I reorganised my code to change the way the object was new-ed and deleted. Memory leak is history.

Thanks for all the help! :)

This topic is closed to new replies.

Advertisement