What is your favorite Windbg tip / trick?

I realized that Windbg is a very powerful debugger for the Windows platform, and I will learn something new about it from time to time. Can Windbg users share their crazy skills?

ps: I'm not looking for a great team, this can be found in the documentation. How about sharing tips on what you couldn't imagine can be done with windbg? for example, Some way to generate statistics about memory allocation when a process is running under the wind.

+45
c ++ debugging windows windbg
Sep 24 '08 at 14:37
source share
13 answers

My favorite is the .cmdtree <file> command (undocumented, but mentioned in previous releases). This can help open another window (which can be docked) to display useful or frequently used commands. This can help make the user more productive with the tool.

Originally discussed here, an example for the <file> parameter: http://blogs.msdn.com/debuggingtoolbox/archive/2008/09/17/special-command-execute-commands-from-a-customized-user-interface-with -cmdtree.aspx

Example: alt text http://blogs.msdn.com/photos/debuggingtoolbox/images/8954736/original.aspx

+30
Sep 24 '08 at 15:28
source share

Investigate memory leak in a crash dump (since I prefer UMDH for live processes). The strategy is that objects of the same type are distributed the same size.

  • Download the !heap -h 0 command to the WinDbg cdb.exe command line version (for greater speed) to get all heap allocations:
 "C:\Program Files\Debugging Tools for Windows\cdb.exe" -c "!heap -h 0;q" -z [DumpPath] > DumpHeapEntries.log 
  • Use Cygwin to grep a list of distributions, grouping them by size:
 grep "busy ([[:alnum:]]\+)" DumpHeapEntries.log \ | gawk '{ str = $8; gsub(/\(|\)/, "", str); print "0x" str " 0x" $4 }' \ | sort \ | uniq -c \ | gawk '{ printf "%10.2f %10d %10d ( %s = %d )\n", $1*strtonum($3)/1024, $1, strtonum($3), $2, strtonum($2) }' \ | sort > DumpHeapEntriesStats.log 
  • You will get a table that looks like this, for example, telling us that 25529270 allocations of 0x24 bytes occupy almost 1.2 GB of memory.
  8489.52 707 12296 ( 0x3000 = 12288 ) 11894.28 5924 2056 ( 0x800 = 2048 ) 13222.66 846250 16 ( 0x2 = 2 ) 14120.41 602471 24 ( 0x2 = 2 ) 31539.30 2018515 16 ( 0x1 = 1 ) 38902.01 1659819 24 ( 0x1 = 1 ) 40856.38 817 51208 ( 0xc800 = 51200 ) 1196684.53 25529270 48 ( 0x24 = 36 ) 
  • Then, if your objects have vtables, just use the dps command to find some of the 0x24 byte heap allocations in DumpHeapEntries.log to find out the type of objects that take all the memory.
 0:075> dps 3be7f7e8 3be7f7e8 00020006 3be7f7ec 090c01e7 3be7f7f0 0b40fe94 SomeDll!SomeType::`vftable' 3be7f7f4 00000000 3be7f7f8 00000000 

It's crappy, but it works :)

+26
Feb 11 '09 at 16:37
source share

The following command is very convenient when viewing the stack for C ++ objects using vtables, especially when working with versions when quite a lot of things are optimized.

dpp esp range


Ability to load an arbitrary PE file as a dump:

windbg -z mylib.dll


Request GetLastError () with:

! gle


This helps to decode common error codes:

! error error_number
+19
01 Oct '08 at 19:50
source share

Almost 60% of the commands that I use every day.

 dv /i /t ?? this kM (kinda undocumented) generates links to frames .frame x !analyze -v !lmi ~ 

Explanation

  1. dv /i /t [doc]
    1. dv - display the names and values ​​of local variables in the current area
    2. /i - indicate the type of variable: local, global, parameter, function or unknown
    3. /t - display data type of variables
  2. ?? this ?? this [doc]
    1. ?? - evaluate C ++ expression
    2. this - C ++ this pointer
  3. kM [doc]
    1. k - display stack backtrack
    2. M - DML mode. Frame numbers are hyperlinks to a specific frame. For more information about CM, see http://windbg.info/doc/1-common-cmds.html
  4. .frame x [doc]
    1. Switch to frame number x. 0 - frame at the top of the stack, 1 - frame 1 under the 0th frame, etc.
    2. To display local variables from another frame on the stack, first switch to that frame - .frame x , then use dv /i /t . By default, d will show information from the top frame.
  5. !analyze -v [doc1] [doc2- Using the extension! Analyse]
    1. !analyze - analyze extension. Display information about the current exception or error checking. Please note that we use the prefix to run the extension ! .
    2. -v - verbose output
  6. !lmi [doc]
    1. !lmi is the lmi extension. Show detailed information about the module.
  7. ~ [doc]
    1. ~ - displays the status for the specified thread or for all threads in the current process.
+15
01 Oct '08 at 20:12
source share

The β€œtip” that I use most often is the one that saves you from having to touch this annoying mouse so often: Alt + 1

Alt + 1 will put focus in the command window so that you can actually enter the command and so that the up arrow scrolls the history of the commands. However, this does not work if your focus is already in the history of the scrollable command.

Peeve: why are heck key presses ignored when focus is in the source window? It doesn't seem like you can edit the source code from within WinDbg. Alt + 1 .

+10
Feb 11 '09 at 6:15
source share

One word (well, OK, three): DML , i.e. Debugging markup language .

This is a fairly recent addition to WinDbg, and it is not documented in the help file. However, there is some documentation in "dml.doc" in the installation directory for debugging tools for Windows.

Basically, this is HTML-like syntax that you can add to your debugger scripts to format and, more importantly, links. You can use links to call other scripts or even the same script.

My daily work includes the maintenance of the metamoderer, which provides common objects and object relationships for most of the C ++ software. First, to facilitate debugging, I wrote a simple dump script that extracts relevant information from these objects.

Now, with DML, I was able to add links to the output, allowing me to call the same script again on related objects. This allows you to quickly explore the model.

Here is a simplified example. Suppose an object under introspection has a relationship called a reference to another object. r @ $ t0 = $ arg1 $$ arg1 - address of the object to study

 $$ dump some information from $t0 $$ allow the user to examine our reference aS /x myref @@(&((<C++ type of the reference>*)@$t0)->reference ) .block { .printf /D "<link cmd=\"$$>a< <full path to this script> ${myref}\">dump Ref</link> " } 

Obviously, this is a fairly canned example, but this material is really invaluable to me. Instead of hunting around in very complex objects for the right data members (which usually took up to a minute and a different casting and casting trick), everything is automated with one click!

+8
Aug 03 '09 at 10:38
source share
  • .prefer_dml 1

    This modifies many of the built-in commands (e.g. lm ) to display DML output, which allows you to click links instead of running commands. Pretty comfortable ...

  • .reload /f /o file.dll ( /o overwrite the current copy of the character you have)

  • .enable_unicode 1 // Switches the default debugger to Unicode for strings, since all Windows components use Unicode internally, which is very convenient.

  • .ignore_missing_pages 1 // If you do a lot of kernel dump analysis, you will see many errors in that the memory is unloaded. This command will inform the debugger that it stops throwing this warning.

nickname alias ...

Save some time in the debugger. Here are some of mine:

 aS !p !process; aS !t !thread; aS .f .frame; aS .p .process /p /r aS .t .thread /p /r aS dv dv /V /i /t //make dv do your favorite options by default aS f !process 0 0 //f for find, eg f explorer.exe 
+7
Apr 28 '10 at 16:10
source share

Another answer mentioned the command window and Alt + 1 to focus on the command input window. Anyone find it difficult to scroll the command output window without using a mouse?

Well, I recently used AutoHotkey to scroll through the command output window using the keyboard and without exiting the command input window.

 ; WM_VSCROLL = 0x115 (277) ScrollUp(control="") { SendMessage, 277, 0, 0, %control%, A } ScrollDown(control="") { SendMessage, 277, 1, 0, %control%, A } ScrollPageUp(control="") { SendMessage, 277, 2, 0, %control%, A } ScrollPageDown(control="") { SendMessage, 277, 3, 0, %control%, A } ScrollToTop(control="") { SendMessage, 277, 6, 0, %control%, A } ScrollToBottom(control="") { SendMessage, 277, 7, 0, %control%, A } #IfWinActive, ahk_class WinDbgFrameClass ; For WinDbg, when the child window is attached to the main window !UP::ScrollUp("RichEdit50W1") ^k::ScrollUp("RichEdit50W1") !DOWN::ScrollDown("RichEdit50W1") ^j::ScrollDown("RichEdit50W1") !PGDN::ScrollPageDown("RichEdit50W1") !PGUP::ScrollPageUp("RichEdit50W1") !HOME::ScrollToTop("RichEdit50W1") !END::ScrollToBottom("RichEdit50W1") #IfWinActive, ahk_class WinBaseClass ; Also for WinDbg, when the child window is a separate window !UP::ScrollUp("RichEdit50W1") !DOWN::ScrollDown("RichEdit50W1") !PGDN::ScrollPageDown("RichEdit50W1") !PGUP::ScrollPageUp("RichEdit50W1") !HOME::ScrollToTop("RichEdit50W1") !END::ScrollToBottom("RichEdit50W1") 

After running the script, you can use Alt + up / down to scroll one line of the command output window, Alt + PgDn / PgUp to scroll one screen.

Note. It seems that different versions of WinDbg will have different class names for the window and controls, so you can use the spy window tool provided by AutoHotkey to first find the actual class names.

+4
Nov 28 '09 at 10:50
source share

Script download SOS based on version of .NET framework (v2.0 / v4.0):

 !for_each_module .if(($sicmp( "@#ModuleName" , "mscorwks") = 0) ) {.loadby sos mscorwks} .elsif ($sicmp( "@#ModuleName" , "clr") = 0) {.loadby sos clr} 
+4
Sep 13 '10 at 14:30
source share

I like to use advanced breakpoint commands, such as using breakpoints to create new one-time breakpoints.

+3
Dec 22 '08 at 20:37
source share

Do not use the WinDbg .heap -stat . Sometimes this leads to an incorrect exit. Use the DebugDiags error report instead.

With the correct numbers, you can use the WinDbg .heap -flt ... .

+1
05 Oct '08 at 12:59
source share

For command and simple (static or automated) routines that use the debugger, it is very cool to be able to run all the debugger commands in a text command file and run them as input through kd.exe or cdb.exe, called through a script package, etc. d.

Run this when you need to do the same old routine without having to run WinDbg and do something manually. It is a pity that this does not work when you are not sure what you are looking for, or some command parameters need manual analysis to find / get.

+1
Jul 16 '10 at 3:19
source share

Server independent dump string for managed code that will work for x86 / x64:

 j $ptrsize = 8 'aS !ds .printf "%mu \n", c+';'aS !ds .printf "%mu \n", 10+' 

Here is a usage example:

 0:000> !ds 00000000023620b8 MaxConcurrentInstances 
+1
Feb 02 2018-11-11T00:
source share



All Articles