Updated Archive of the Debug Ninja’s Twitter Debug Tips
Every Wednesday (usually) I post a debug tip to our twitter page at https://twitter.com/#!/ntdebugging. This blog is an archive of these tips to allow our readers to find this information easily. I will update this blog periodically with the new tips; follow us on twitter if you want to see the tips as I post them.
The goal of these tips is to share debug commands, and forms of commands (parameters, flags, etc) that my colleagues and I find useful. I hope you can add these commands to your toolkit and they will help you debug more efficiently.
Tips:
!thread/!process [address] e - on x64 will not show you the meaningless Args to Child information.
.frame /c [FrameNumber] - sets context to specified stack frame. Provides more reliable information than .trap on x64.
kn - Dumps call stack with frame numbers, easier than counting stacks for .frame.
.frame /r [FrameNumber] - same as .frame /c, but shows registers without changing context.
Note: With .frame /c or /r you can only trust the nonvolatile registers. See https://msdn.microsoft.com/en-us/library/9z1stfyw(VS.80).aspx for vol/nonvol regs.
k=rbp rip FrameCount - Dumps call stack starting at rbp/rip on x64. Useful when the stack is corrupt. #debug ^DN
.process/.thread /p /r [address] - sets new process context, sets .cache forcedecodeuser, and reloads user symbols. #debug ^DebugNinja
!process [address] 17 - Sets the context for this command, avoids the need for .process to see user stacks. Try !process 0 17 #debug ^DN
~~[ThreadID]s - Changes threads in user mode. Use Thread ID number from output such as !locks. Ex: ~~[1bd4]s #debug ^DN
runas /netonly /u:<account> windbg.exe - Launch windbg with domain account. Use when dbg computer isn't in domain and symbol server is. ^DN
!heap -p -a <address> - Shows information about the heap block containing <address>, even if you aren't using pageheap. #debug ^DN
ub - Unassembles starting at a location prior to your address. Accepts l<number> to specify how many instructions to go back. ub . l20 ^DN
!stacks 2 [FilterString] - Finds kernel mode call stacks that contain the FilterString in a symbol. #debug ^DN
!thread [address] 17 (or 1e on x64) - Sets context for this command, avoids the need for .thread/.process for user stacks. #debug ^DN
.hh [Text] - Opens the debugger help. [Text] is the topic to lookup in the index. Example: .hh !pte #debug ^DN
?? can dump structs using C++ style expressions. Ex: ??((nt!_KTHREAD*)(0xfffffa800ea43bb0))->ApcState #debug ^DN
bp /t EThread - Sets a kernel mode breakpoint that only triggers when hit in the context of this thread. #debug ^DN
bp /p EProcess - Sets a kernel mode breakpoint that only triggers when hit in the context of this process. #debug ^DN
gc - If you run 'p' and hit a breakpoint, gc takes you where p would have gone if you had not hit the bp. #debug ^DN
gu - Go until the current function returns. Effectively this unwinds one stack frame. #debug #windbg ^DN
pc - Steps through until the next 'call' instruction. Combine with other commands to find who returned your error> pc;p;r eax #debug ^DN
pt - Steps through until the next 'ret' instruction. Similar to gu, but pt stops on the ret and gu stops after the ret. #debug ^DN
.ignore_missing_pages 1 - supresses the error: "Page 2a49 not present in the dump file. Type ".hh dbgerr004" for details" #debug ^DN
.exr -1 shows the most recent exception. Useful in user dumps of crashes, especially for no execute crashes (NX/DEP). #debug ^DN
wt - Trace calls until they return to the current address. More useful with -or to get return values. Use -l for depth. ^DN #debug
.thread /w - Changes to the WOW64 32-bit context from 64-bit kernel mode. Wow64exts doesn't work in kernel mode. #debug ^DN
??sizeof(structure) - Gets the size of a structure, it's easier than counting. #debug ^DN
sxe ld:module.dll - Enables an exception which will break into the debugger when module.dll is loaded. #debug ^DN
vertarget - Shows OS version of the debug target. Also shows machine name, uptime, and session time (when the dump was taken). #debug ^DN
!vm 1 - In a kernel debugger, shows basic information about memory usage. Available, committed, pagefile, pool, sysptes, etc. #debug ^DN
.time - Shows session time (when dump was taken) and system uptime. In user mode shows process uptime, kernel/user time. #debug ^DN
ba w size [address] - Break on write access only. Replace size with the num bytes you want to watch. Ex: ba w 4 005d5f10 #debug ^DN
.bugcheck - Displays the bugcheck code of a blue screen crash. The format is more concise than !analyze. #debug ^DN
.process -i <address> - Make the process active and break into the debugger. Use in live kernel debugs to get into process context. ^DN
.reload /f /o - Overwrites cached files in your downstream symbol store. Useful when your store has corrupt pdbs. #debug ^DN
->* - Use with dt to dump pointers. Example: dt _EPROCESS [Address] ObjectTable->*
!for_each_module s -a @#Base @#End "PTag" - Find the drivers using pool tag "PTag". #debug ^DN
.unload [DllName] - Unloads the debug extension you didn't intend to load. Omit DllName to unload the last dll loaded. #debug ^DN
!exqueue dumps the executive worker queues. Use flags 7f to dump the worker threads and the queues. #debug ^DN
lmvm <module> - Dumps information about the module. Remember to use <module> and not <module.dll>. #debug ^DN
Comments
- Anonymous
July 20, 2011
Very useful, thank you, mysterious debug ninja!