Thursday, September 22, 2011

ba (Break on Access) in WinDbg

There was an Access Violation case during test run. It turned out that one private member, which is supposed to be accessed only from application init routine and exit routine, was overwritten by unknown thread / function.

Break on memory access command - ba command - is very useful for this kind of case. ba allows us to see who is touching the variable. To simplify the case and demonstrate it easily, I will use notepad.exe in WinDBG.

1) Run notepad.exe from WinDBG

   C> Windbg  notepad.exe

2) Run notepad.exe until you see UI by typing "g"
3) Pause notepad process in windbg
4) In Windbg, check any global variable of notepad process
0:000> x notepad!g_*
00000000`ff6f0050 notepad!g_fFontSettingChanged = 
00000000`ff6f0b28 notepad!g_fUISettingChanged = 
00000000`ff6f0200 notepad!g_PageSetupDlg = 
00000000`ff6f1e70 notepad!g_lExisting = 
00000000`ff6f2720 notepad!g_ftSaveAs = 
00000000`ff6f0b2c notepad!g_fPageSetupChanges = 
00000000`ff6f0100 notepad!g_wpOrig = 
00000000`ff6f0088 notepad!g_ftOpenedAs = 

Here let's pick a variable (notepad!g_ftOpenedAs).

5) Set breakpoint with ba command.
0:001> ba w4 notepad!g_ftOpenedAs ".echo ******; ~. ; kp; g;"

ba command will break into debugger when the specified memory is accessed by any thread / any function. w4 means the debugger will break into if any method is writing to the specificed memory area. second parameter notepad!g_ftOpenedAs is the memory location to watch. And the last parameter is the command that will run when break occurs. If no command is specified, it will break into the debugger and wait at prompt. The command is (1)first print six asterisks, (2) show current thread (~.), (3) show current thread call stack (kp), (4) keep running without break into debugger (g).



6) Run notepad process again ("g")

7) In notepad UI, click File->Open. In Open File Dialog, click Cancel.
This is to let a thread to write a value to global variable.

8) Now, you can see who is touching notepad!g_ftOpenedAs variable by look at the call stack output.

******
.  0  Id: 1290.dbc Suspend: 1 Teb: 000007ff`fffdd000 Unfrozen
      Start: notepad!WinMainCRTStartup (00000000`ff6e3570) 
      Priority: 0  Priority class: 32  Affinity: f
Child-SP          RetAddr           Call Site
00000000`0019f7b0 00000000`ff6e14eb notepad!NPCommand+0x3fa
00000000`0019f8e0 00000000`77b8c3c1 notepad!NPWndProc+0x540
00000000`0019f920 00000000`77b8c60a USER32!UserCallWinProcCheckWow+0x1ad
00000000`0019f9e0 00000000`ff6e10bc USER32!DispatchMessageWorker+0x3b5
00000000`0019fa60 00000000`ff6e133c notepad!WinMain+0x16f
00000000`0019fae0 00000000`77a6f56d notepad!DisplayNonGenuineDlgWorker+0x2da
00000000`0019fba0 00000000`77ca2cc1 kernel32!BaseThreadInitThunk+0xd
00000000`0019fbd0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

If you're in live debug mode, you can simply break into the debugger to look into suspicious thread.

Tuesday, September 20, 2011

How to use UMDH

UMDH (User Mode Dump Heap) tool  in 'Debugging Tools for Windows'  analyze Windows heap memory and useful for detecting native memory leak.

Here is brief summary of how to use it.

(a) Run gflags.exe. Select [Image File], type filename and check [Create user mode stack trace database].
     This enables data collection for the specifc process.


     Alternatively the command line below can be run:
                   C> gflags -i notepad.exe +ust

(b) Set symbol path.
     C>  SET _NT_SYMBOL_PATH=c:\symbols

(c) Run UMDH.EXE
     Take first snapshot of memory and run your application until memory leak.
     Taks second snapshot and compare two snapshots and get the difference.

    C>umdh -p:2868 > firstsnap.txt             <== take first snapshot
    C>umdh -p:2868 > secondsnap.txt        <== take 2nd snapshot
    C>umdh firstsnap.txt secondsnap.txt > diff.txt       <== create diff file
    C>notepad.exe diff.txt      <== check the result