C++ 您最喜欢的 Windbg 提示/技巧是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/127564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is your favourite Windbg tip/trick?
提问by user15071
I have come to realize that Windbg is a very powerful debugger for the Windows platform & I learn something new about it once in a while. Can fellow Windbg users share some of their mad skills?
我逐渐意识到 Windbg 是一个非常强大的 Windows 平台调试器,我偶尔会学到一些新的东西。Windbg 用户可以分享他们的一些疯狂技能吗?
ps: I am not looking for a nifty command, those can be found in the documentation. How about sharing tips on doing something that one couldn't otherwise imagine could be done with windbg? e.g. Some way to generate statistics about memory allocations when a process is run under windbg.
ps:我不是在寻找漂亮的命令,可以在文档中找到。分享一些关于使用windbg 做一些人们无法想象的事情的技巧怎么样?例如,当进程在windbg 下运行时生成有关内存分配的统计信息的一些方法。
回答by Kris Kumler
My favorite is the command .cmdtree <file>
(undocumented, but referenced in previous release notes). This can assist in bringing up another window (that can be docked) to display helpful or commonly used commands. This can help make the user much more productive using the tool.
我最喜欢的是命令.cmdtree <file>
(未记录,但在以前的发行说明中引用)。这可以帮助调出另一个窗口(可以停靠)以显示有用或常用的命令。这有助于提高用户使用该工具的工作效率。
Initially talked about here, with 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
最初讲到这里,以<file>
参数为例: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
示例: 替代文本 http://blogs.msdn.com/photos/debuggingtoolbox/images/8954736/original.aspx
回答by jturcotte
To investigate a memory leak in a crash dump (since I prefer by far UMDH for live processes). The strategy is that objects of the same type are all allocated with the same size.
调查故障转储中的内存泄漏(因为我目前更喜欢 UMDH 用于实时进程)。策略是相同类型的对象都以相同的大小分配。
- Feed the
!heap -h 0
command to WinDbg's command line version cdb.exe (for greater speed) to get all heap allocations:
- 将
!heap -h 0
命令提供给 WinDbg 的命令行版本 cdb.exe(以获得更快的速度)以获取所有堆分配:
"C:\Program Files\Debugging Tools for Windows\cdb.exe" -c "!heap -h 0;q" -z [DumpPath] > DumpHeapEntries.log
"C:\Program Files\Debugging Tools for Windows\cdb.exe" -c "!heap -h 0;q" -z [DumpPath] > DumpHeapEntries.log
- Use Cygwinto grep the list of allocations, grouping them by size:
- 使用Cygwin来 grep 分配列表,按大小对它们进行分组:
grep "busy ([[:alnum:]]\+)" DumpHeapEntries.log \ | gawk '{ str = ; gsub(/\(|\)/, "", str); print "0x" str " 0x" }' \ | sort \ | uniq -c \ | gawk '{ printf "%10.2f %10d %10d ( %s = %d )\n", *strtonum()/1024, , strtonum(), , strtonum() }' \ | sort > DumpHeapEntriesStats.log
grep "busy ([[:alnum:]]\+)" DumpHeapEntries.log \ | gawk '{ str = ; gsub(/\(|\)/, "", str); print "0x" str " 0x" }' \ | sort \ | uniq -c \ | gawk '{ printf "%10.2f %10d %10d ( %s = %d )\n", *strtonum()/1024, , strtonum(), , strtonum() }' \ | sort > DumpHeapEntriesStats.log
- You get a table that looks like this, for example, telling us that 25529270 allocations of 0x24 bytes take nearly 1.2 GB of memory.
- 例如,您会得到一个看起来像这样的表,它告诉我们 25529270 次 0x24 字节的分配占用了近 1.2 GB 的内存。
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 )
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 seek some of the 0x24 bytes heap allocations in DumpHeapEntries.log to know the type of the objects that are taking all the memory.
- 然后,如果您的对象具有 vtables,只需使用该
dps
命令在 DumpHeapEntries.log 中寻找一些 0x24 字节的堆分配,以了解占用所有内存的对象的类型。
0:075> dps 3be7f7e8 3be7f7e8 00020006 3be7f7ec 090c01e7 3be7f7f0 0b40fe94 SomeDll!SomeType::`vftable' 3be7f7f4 00000000 3be7f7f8 00000000
0:075> dps 3be7f7e8 3be7f7e8 00020006 3be7f7ec 090c01e7 3be7f7f0 0b40fe94 SomeDll!SomeType::`vftable' 3be7f7f4 00000000 3be7f7f8 00000000
It's cheesy but it works :)
这很俗气,但它有效:)
回答by deemok
The following command comes very handy when looking on the stack for C++ objects with vtables, especially when working with release builds when quite a few things get optimized away.
在使用 vtables 在堆栈中查看 C++ 对象时,以下命令非常方便,尤其是在处理发布版本时,很多事情都得到了优化。
dpp esp Range
dpp esp范围
Being able to load an arbitrary PE file as dump is neat:
能够将任意 PE 文件作为转储加载是很整洁的:
windbg -z mylib.dll
windbg -z mylib.dll
Query GetLastError() with:
使用以下命令查询 GetLastError():
!gle
!gle
This helps to decode common error codes:
这有助于解码常见错误代码:
!error error_number
!error error_number
回答by deemok
Almost 60% of the commands I use everyday..
几乎 60% 我每天使用的命令..
dv /i /t
?? this
kM (kinda undocumented) generates links to frames
.frame x
!analyze -v
!lmi
~
Explanation
解释
dv /i /t
[doc]dv
- display names and values of local variables in the current scope/i
- specify the kind of variable: local, global, parameter, function, or unknown/t
- display data type of variables
?? this
[doc]??
- evaluate C++ expressionthis
- C++ this pointer
kM
[doc]k
- display stack back traceM
- DML mode. Frame numbers are hyperlinks to the particular frame. For more info about kM refer to http://windbg.info/doc/1-common-cmds.html
.frame x
[doc]- Switch to frame number x. 0 being the frame at top of stack, 1 being frame 1 below the 0th frame, and so on.
- To display local variables from another frame on the stack, first switch to that frame -
.frame x
, then usedv /i /t
. By defaultd
will show info from top frame.
!analyze -v
[doc1][doc2 - Using the !analyze Extension]!analyze
-analyze
extension. Display information about the current exception or bug check. Note that to run an extension we prefix!
.-v
- verbose output
!lmi
[doc]!lmi
-lmi
extension. Display detailed information about a module.
~
[doc]~
- Displays status for the specified thread or for all threads in the current process.
dv /i /t
[文档]dv
- 显示当前作用域中局部变量的名称和值/i
- 指定变量类型:局部、全局、参数、函数或未知/t
- 显示变量的数据类型
?? this
[文档]??
- 评估 C++ 表达式this
- C++ this 指针
kM
[文档]k
- 显示堆栈回溯M
- DML 模式。帧号是指向特定帧的超链接。有关 kM 的更多信息,请参阅http://windbg.info/doc/1-common-cmds.html
.frame x
[文档]- 切换到帧号 x。0 是堆栈顶部的帧,1 是第 0 帧下方的第 1 帧,依此类推。
- 要显示堆栈上另一个帧的局部变量,首先切换到该帧 -
.frame x
,然后使用dv /i /t
. 默认情况下d
将显示来自顶部框架的信息。
!analyze -v
[doc1] [doc2 - 使用 !analyze 扩展]!analyze
-analyze
扩展。显示有关当前异常或错误检查的信息。请注意,要运行扩展程序,我们将!
.-v
- 详细输出
!lmi
[文档]!lmi
-lmi
扩展。显示有关模块的详细信息。
~
[文档]~
- 显示指定线程或当前进程中所有线程的状态。
回答by JeffJ
The "tip" I use most often is one that will save you from having to touch that pesky mouse so often: Alt+ 1
我最常使用的“提示”可以让您不必经常触摸那个讨厌的鼠标:Alt+1
Alt+ 1will place focus into the command window so that you can actually type a command and so that up-arrow actually scrolls through command history. However, it doesn't work if your focus is already in the scrollable command history.
Alt+1将焦点放在命令窗口中,以便您可以实际键入命令,并且向上箭头实际上可以滚动查看命令历史记录。但是,如果您的焦点已经在可滚动命令历史记录中,则它不起作用。
Peeve: why the heck are key presses ignored while the focus is in a source window? It's not like you can edit the source code from inside WinDbg. Alt+ 1to the rescue.
Peeve:当焦点在源窗口中时,为什么按键会被忽略?您不能从 WinDbg 内部编辑源代码。Alt+1救援。
回答by Nicolas Lefebvre
One word (well, OK, three) : DML, i.e. Debugger Markup Language.
一个词(好吧,好吧,三个):DML,即调试器标记语言。
This is a fairly recent addition to WinDbg, and it's not documented in the help file. There is however some documentation in "dml.doc" in the installation directory for the Debugging Tools for Windows.
这是 WinDbg 的一个相当新的补充,它没有记录在帮助文件中。但是,Windows 调试工具的安装目录中的“dml.doc”中有一些文档。
Basically, this is an HTML-like syntax you can add to your debugger scripts for formatting and, more importantly, linking. You can use links to call other scripts, or even the same script.
基本上,这是一种类似于 HTML 的语法,您可以将其添加到调试器脚本中以进行格式化,更重要的是,用于链接。您可以使用链接来调用其他脚本,甚至是同一个脚本。
My day-to-day work involves maintenance on a meta-modeler that provides generic objects and relationship between objects for a large piece of C++ software. At first, to ease debugging, I had written a simple dump script that extracts relevant information from these objects.
我的日常工作涉及维护元建模器,该元建模器为大量 C++ 软件提供通用对象和对象之间的关系。起初,为了便于调试,我编写了一个简单的转储脚本,从这些对象中提取相关信息。
Now, with DML, I've been able to add links to the output, allowing the same script to be called again on related objects. This allows for much faster exploration of a model.
现在,使用 DML,我已经能够向输出添加链接,允许在相关对象上再次调用相同的脚本。这允许更快地探索模型。
Here's a simplified example. Assume the object under introspection has a relationship called "reference" to another object. r @$t0 = $arg1 $$ arg1 is the address of an object to examine
这是一个简化的示例。假设被内省的对象与另一个对象具有称为“引用”的关系。r @$t0 = $arg1 $$ arg1 是要检查的对象的地址
$$ 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 a pretty canned example, but this stuff is really invaluable for me. Instead of hunting around in very complex objects for the right data members (which usually took up to a minute and various casting and dereferencing trickery), everything is automated in one click!
显然,这是一个非常好的例子,但这些东西对我来说真的是无价之宝。无需在非常复杂的对象中寻找正确的数据成员(通常需要长达一分钟的时间以及各种转换和取消引用技巧),一切都可以通过单击自动完成!
回答by JasonE
.prefer_dml 1
This modifies many of the built in commands (for example,
lm
) to display DML output which allows you to click links instead of running commands. Pretty handy....reload /f /o file.dll
(the/o
will overwrite the current copy of the symbol you have).enable_unicode 1
//Switches the debugger to default to Unicodefor strings since all the Windows components use Unicode internally, this is pretty handy..ignore_missing_pages 1
//If you do a lot of kernel dump analysis, you will see a lot of errors regarding memory being paged out. This command will tell the debugger to stop throwing this warning.
.prefer_dml 1
这会修改许多内置命令(例如,
lm
)以显示 DML 输出,从而允许您单击链接而不是运行命令。蛮好用的....reload /f /o file.dll
(/o
将覆盖您拥有的符号的当前副本).enable_unicode 1
//将调试器切换为字符串的默认Unicode,因为所有 Windows 组件内部都使用 Unicode,这非常方便。.ignore_missing_pages 1
//如果你做大量的内核转储分析,你会看到很多关于内存被分页的错误。此命令将告诉调试器停止抛出此警告。
alias alias alias...
别名别名别名...
Save yourself 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, e.g. f explorer.exe
回答by Naveen
回答by wangzq
Another answer mentioned the command window and Alt+ 1to focus on the command input window. Does anyone find it difficult to scroll the command output window without using the mouse?
另一个答案提到了命令窗口和Alt+1以关注命令输入窗口。有没有人觉得不使用鼠标很难滚动命令输出窗口?
Well, I have recently used AutoHotkeyto scroll the command output window using keyboard and without leaving the command input window.
好吧,我最近使用AutoHotkey使用键盘滚动命令输出窗口,而无需离开命令输入窗口。
; 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 this script is run, you can use Alt+ up/downto scroll one line of the command output window, Alt+ PgDn/PgUpto scroll one screen.
运行此脚本后,您可以使用Alt+ up/down滚动一行命令输出窗口,使用Alt+ PgDn/PgUp滚动一屏。
Note: it seems different versions of WinDbg will have different class names for the window and controls, so you might want to use the window spy tool provided by AutoHotkey to find the actual class names first.
注意:似乎不同版本的 WinDbg 对窗口和控件有不同的类名,因此您可能需要使用 AutoHotkey 提供的窗口间谍工具首先找到实际的类名。
回答by Brian
I like to use advanced breakpoint commands, such as using breakpoints to create new one-shot breakpoints.
我喜欢使用高级断点命令,例如使用断点创建新的一次性断点。