Showing posts with label Debugging. Show all posts
Showing posts with label Debugging. 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”,

Tuesday, December 7, 2010

BoundsCheck not working with mixed codes

Previously, we have tried to use BoundsChecker to test our mixed programs. But it does not support managed code and also cause huge memory usage during running,

Recently, I tried "Application Verifier", a great tool distributed by Microsoft, can be used alone or together with Visual studio team version,
and it seems to be acceptable. The below code can be found immediately:

   1: int* p = new int[10];
   2: p[11]=1;       // this cannot be detected, since the heap block has additional 8-bytes suffix, it seems that AppVerif does not check with this
   3: p[100] = 1;   // this can be detected immediately, since AppVerif generates memory fence after the heap block.

After running with Application Verifier, the memory usage is also acceptable.

Another thing related to this is that AppVerif can only work with native codes. As for the mixed code, msdn does not say clearly.
Two potential results can be:
1: AppVerif can only check native memory, ignore managed objects.
2: AppVerif cannot deal with mixed code correctly, may corrupt program's running by mistake.

After research work, I found the below link: saying that AppVerif does not actually validate the managed objects and codes,
instead it validates the CLR itself. If so, it seems that it can work for checking native memory overwriting.


http://social.msdn.microsoft.com/forums/en-US/vstsappverifier/thread/7f5e85c4-c715-43cf-af6f-e4917cfd7108/

Setting data breakpoints for mixed projects in VS2008

In VS2008, data breakpoints are disabled in GUI for mixed projects, which is actually a powerful debugging mechanism for trouble-shooting. Although it could still be set in windbg, still painful.

Fortunately, data breakpoints can be set programmatically. We can found one sample from below link:
http://www.morearty.com/code/breakpoint/

Then, in your projects, try below code:

 
   1: DWORD x = 1;
   2: CBreakpoint bp;
   3: bp.Set(&x, sizeof(x), CBreakpoint::Write);
   4: ...
   5: x = 100;
   6:  
Generally, I would like to create an foo debugging thread, keep looping/sleeping, if needed, explicitly set the watch target dynamically in the debugger, then it works well.