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

Wednesday, December 8, 2010

VS Tips (Continuously updated)

  • Special commands in Immediate/Watch windows
    • c# temp variables defined in Immediate Window

input “int tempVar = 0;” in the immediate window, then type $temp or @temp in Watch window, see what happens. Can be helpful combined with the usage of Conditional Breakpoints.

VS can even create an object in immediate window, like Something s = new Something();

    • Time-measurement feature by conditional breakpoint

set a trace point, and change the statement as below:

{@clk}, {@clk=0}, $FUNCTION

on my 64-bit win7, time resolution is 10-6 second

see what happensSmile

    • control var’s display suffix
      • var,h: in watch window shows hex value
      • var,nq: show string without escaped quotes, helpful when showing “\””
      • var,ac: force to evaluate the expression even if “implicit expression evaluation” is disabled in debug-general setting. May be helpful to watch some variables which has nasty side effect when auto evaluate expression, like properties
    • watch objects out of scope: “Make Object Id”, then watch by “1#”, “2#”, etc. Even if the object is being GCed.
    • pseudo-vars in watch windows:
      • $exception
      • $user
    • Visualizer in watch window
      • for c#:
        • MyDocument\Visual Studio 2008\Visualizer\autoexp.cs and autoexp.dll
        • write your own visualizer plug-in
        • customize debugdisplay attribute in c# classes
      • for native c++: c:\program files(x86)\visual studio 2008\common7\packages\debugger\autoexp.dat
    • Execute SOS from immediate window

.load sos

note: only 32bit mixed debugging mode supports this

  • Debugger Behavior
    • Set Breakpoint at any system function

type “{,,user32.dll}_SendMessageA@16” in the New breakpoint window

some function has different symbol name, like: LockWindowUpdate

{,,user32.dll}_NtUserLockWindowUpdate@4 should be used.

    • Why Edit&Continue not working for my project?

refer to below link:

http://msdn.microsoft.com/en-us/library/ms164927%28v=VS.80%29.aspx

some common cases when E&C not available are:

mixed debugging

64-bit CLR

attached by debugger and not started from debugger

    • Why my VS cannot detach from the target

when attaching to the target, remember to choose Managed only mode, not mixed mode

  • Misc
    • Dump
      • VS-generated minidump has no handle info, so not good for multiple thread deadlock troubleshooting

Tuesday, December 7, 2010

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.