Sign in to follow this  
sipickles

Rooting out a memory leak with tools

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 );

Share this post


Link to post
Share on other sites
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 leak
projector = new CCamera( cam );




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

Weird!

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
I reorganised my code to change the way the object was new-ed and deleted. Memory leak is history.

Thanks for all the help! :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this