Showing posts with label WinDbg. Show all posts
Showing posts with label WinDbg. Show all posts

Sunday, December 12, 2010

memory leak detection notes (continuously updating)

Memory leak problem is very common, below is some my previous working notes:

  • BoundsCheck

BoundsCheck does not work well with mixed codes. Since my latest projects are almost all mixed, so, seldom used in my daily work.

  • Visual studio
    • Enable memory leak reporting

There are two ways to enable memory leak check in VC, one is to define DEBUG_NEW macro, another is as below:

   1: #define _CRTDBG_MAP_ALLOC 
   2: #include<stdlib.h> 
   3: #include<crtdbg.h>

Then calling _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); when initializing your app.


With the above changes, visual studio can dump memory block leak when quitting or between two snapshot via Windows API. For instance:


c:\program files(x86)\microsoft visual studio\vc98\include\crtdbg.h(552) : {43} normal
block at 0x00441C20, 40 bytes long.
Data: < C > 08 02 43 00 16 00 00 00 00 00 00 00 00 00 00 00



    • Output mode

The above output is one sample of block leak, in which, {43} is the heap block allocation id, which can be used to set breakpoints. “normal” is the classification of heap blocks, some other types include: client/crt/free (free will no appear here). Then double click the output item, the allocation location can be watched.

By default, visual studio generate the report to the output window, which can also be changed by CrtSetReportMode calling, for instance: to std-err console or some files (needing to call _CrtSetReportFile first)



    • Conditional breakpoint by allocation #

Input {,,msvcrtd.dll}_crtBreakAlloc in your watch window, by default value would be –1, which is the condition when allocation would be broken, for instance, 43, and when the allocation # equals to 43, DbgBreak is triggered. The value can be changed manually in visual studio.

You can also call _CrtSetBreakAlloc(43) to do the same thing.



    • create memory snapshot and compare difference


   1: _CrtMemState s1, s2, s3;
   2: _CrtMemCheckpoint( &s1 );
   3: _CrtMemCheckpoint( &s2 );
   4: if ( _CrtMemDifference( &s3, &s1, &s2) )
   5:     _CrtMemDumpStatistics( &s3 );

The above codes show how to do this. In the middle, CrtMemDumpStatistics can be used to generate statistics info for each _CrtMemState snapshot.


  • AppVerif and Windbg

We can also get stacktrace for each leaking block above by enable it in gflags.exe. Then, attaching your target with WinDbg, check the stacktrace info for each heap by typing:

!heap –p –a <blockAddr>

Then, the block info like type, stacktrace will be displayed.


  • LeakDiag vs UMPH

Both these tools can help us generate memory leak reports. UMPH can work only with standard heap allocation, while LeakDiag can work with all 6 types of allocations:

standard windows heap allocation

virtual memory allocator

MPHeap allocator

COM Allocator

COM Internal Allocator

C Runtime Allocator

With LeakDiag, you can simply create two snapshots, then compare them as you wish, similar to the above steps in visual studio. Then, a final xml file can be generated.

one sample can be found:

http://mcfunley.com/277/using-leakdiag-to-debug-unmanaged-memory-leaks

http://thetweaker.wordpress.com/2009/04/09/native-memory-leaks-part-1-leakdiag/



    • Visualizing the report

For LeakDiag, there are some tools to view the report, like: “Leak XML Logfile Analyzer”, “LDGrapher”,

Friday, December 10, 2010

WinDbg debugging scenario (2) find clr gchandle leak

 

!gchandleleak can search heap to get referenced handles, may have false positive. But if the number keeps increasing after each specific operation, then it may cause handle leaks.

!do poi(handleValue) to see what is contained by the handle.

 

For most cases, PowerDbg can be used to automatically check the leakages.

Windbg Debugging Scenario (1): Finding un-disposed objects

 

Use !finalizequeue to find all disposible objects, then use !gcroot to check whether they are orphan, then dump the orphaned objects, in most case, developers will define some private flags like _IsDisposed or _IsClosed, if already orphaned, should be true.

 

generally, the steps can be completed by PowerDbg scripts.

Wednesday, December 8, 2010

PowerDbg: a great module to write windbg script

Last week during the trip in Las Vegas, I learned something about PowerDbg, a PowerShell module which can automate windbg debugging. It is really a exciting tool and just what I have been searching for a long time.
During the debugging, we may wish to analyze elements in a big array one by one, but manually doing so is too troublesome, for instance, one of the element is not disposed or one of the element's flag is not set correctly.
In this case, if a script can help us do it automatically, it would be great.
PowerShell is microsoft's new shell replacing the old WSH. It is strong typed and based on .net framework, can access all .net framework.
It can also be integrated with windbg: Windbg works as debugging server, PowerDbg as remoting host, sends debugging commands to windbg,
retrieves output, parses them and continues analysis.
One sample is like:
http://www.leeholmes.com/blog/2009/01/21/scripting-windbg-with-powershell/
PowerDbg can be downloaded from:
http://powerdbg.codeplex.com/
The latest staple build is 5.3, I did not try the 6.0(alpha). I strongly suggest the pscx and powertab modules. The first is an extension for powershell and the latter can provide intelligence in shell.
I will later post some of my sample scripts.