windbg 是非常强大的调试工具,但是在使用windbg 进修调试时候,很多的命令不知道如何使用。文章简单介绍如何使用windbg进行调试
https://docs.microsoft.com/zh-cn/windows-hardware/drivers/debugger/debugger-download-tools
https://docs.microsoft.com/zh-cn/windows-hardware/drivers/debugger/debugger-download-tools
可用于 CDB、KD 和 WinDbg 的各种调试器 元命令,这些命令前面都有一个点。可以对进程数据进行显示和调整。
例如:.ecxr 命令显示与当前异常关联的上下文记录。
0:000> .ecxr
eax=00000000 ebx=1e7cb010 ecx=00000000 edx=00000001 esi=66a0eba0 edi=3951c6b0
eip=0012abe0 esp=00cf8df0 ebp=00cf8e38 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210216
lec_teacher!GoodsPreviewWidget::getShowMode:
0012abe0 8b411c mov eax,dword ptr [ecx+1Ch] ds:002b:0000001c=????????
可用于 CDB、KD 和 WinDbg 的各种调试器 命令。这些命令主要是内部调试使用。
例如:kb命令就是显示堆栈信息的
0:000> kb
*** Stack trace for last set context - .thread/.cxr resets it
# ChildEBP RetAddr Args to Child
00 00cf8dec 002da5ca 96b6b062 3951c6b0 40f28218 lec_teacher!GoodsPreviewWidget::getShowMode [d:\shendun_lec_teacher\origin\version\1.5.7\src\plugin\activity\goods\goodspreviewwidget.cpp @ 22]
01 00cf8e38 66a0c9ba 00000001 3951c6b0 1e7cb010 lec_teacher!GraphicsToolManager::onCountDownAccepted+0x7a [d:\shendun_lec_teacher\origin\version\1.5.7\src\tool\graphics\manager\graphicstoolmanager.cpp @ 739]
02 (Inline) -------- -------- -------- -------- Qt5Core!QtPrivate::QSlotObjectBase::call+0x17 [c:\users\qt\work\qt\qtbase\src\corelib\kernel\qobjectdefs_impl.h @ 394]
03 00cf8ed0 66a0cc8e 40f26bc8 66d48844 66d48844 Qt5Core!QMetaObject::activate+0x40a [c:\users\qt\work\qt\qtbase\src\corelib\kernel\qobject.cpp @ 3774]
04 00cf8ee4 644c8218 40f26bc8 646197f4 00000001 Qt5Core!QMetaObject::activate+0x1e [c:\users\qt\work\qt\qtbase\src\corelib\kernel\qobject.cpp @ 3646]
05 (Inline) -------- -------- -------- -------- Qt5Widgets!QDialog::rejected+0xb [c:\users\qt\work\qt\qtbase\src\widgets\.moc\release\moc_qdialog.cpp @ 241]
06 (Inline) -------- -------- -------- -------- Qt5Widgets!QDialogPrivate::finalize+0x23 [c:\users\qt\work\qt\qtbase\src\widgets\dialogs\qdialog.cpp @ 178]
07 00cf8f0c 644843da 00000001 002e5485 96b6b10a Qt5Widgets!QDialog::done+0x38 [c:\users\qt\work\qt\qtbase\src\widgets\dialogs\qdialog.cpp @ 632]
08 00cf8f14 002e5485 96b6b10a 00000000 00000002 Qt5Widgets!QAbstractSpinBox::stepUp+0xa [c:\users\qt\work\qt\qtbase\src\widgets\widgets\qabstractspinbox.cpp @ 617]
09 00cf8f50 003518b2 40f26bc8 00000000 00000002 lec_teacher!CountDownDialog::on_okBtn_clicked+0x165 [d:\shendun_lec_teacher\origin\version\1.5.7\src\tool\graphics\widgets\countdowndialog.cpp @ 204]
0a 00cf8f74 669f5808 00000000 0000002b 00cf9054 lec_teacher!CountDownDialog::qt_metacall+0x32 [d:\shendun_lec_teacher\origin\version\1.5.7\release\moc_countdowndialog.cpp @ 180]
0b 00cf8f84 66a0cacf 40f26bc8 00000000 0000002b Qt5Core!QMetaObject::metacall+0x28 [c:\users\qt\work\qt\qtbase\src\corelib\kernel\qmetaobject.cpp @ 304]
0c 00cf9018 66a0cc8e 32be0c10 66d4871c 66d4871c Qt5Core!QMetaObject::activate+0x51f [c:\users\qt\work\qt\qtbase\src\corelib\kernel\qobject.cpp @ 3813]
0d 00cf902c 643fdd80 32be0c10 6460966c 00000002 Qt5Core!QMetaObject::activate+0x1e [c:\users\qt\work\qt\qtbase\src\corelib\kernel\qobject.cpp @ 3646]
0e (Inline) -------- -------- -------- -------- Qt5Widgets!QAbstractButton::clicked+0x27
用户模式和内核模式调试过程中经常使用的扩展命令。
使用一些扩展库的命令 ext.dll 或 dbghelp.dll
例如:!analyze
0:000> !analyze -v
ADDITIONAL_XML: 1
OS_BUILD_LAYERS: 1
NTGLOBALFLAG: 0
PROCESS_BAM_CURRENT_THROTTLED: 0
PROCESS_BAM_PREVIOUS_THROTTLED: 0
APPLICATION_VERIFIER_FLAGS: 0
CONTEXT: (.ecxr)
eax=00000000 ebx=1e7cb010 ecx=00000000 edx=00000001 esi=66a0eba0 edi=3951c6b0
eip=0012abe0 esp=00cf8df0 ebp=00cf8e38 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210216
lec_teacher!GoodsPreviewWidget::getShowMode:
0012abe0 8b411c mov eax,dword ptr [ecx+1Ch] ds:002b:0000001c=????????
Resetting default scope
EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 0012abe0 (lec_teacher!GoodsPreviewWidget::getShowMode)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000000
Parameter[1]: 0000001c
Attempt to read from address 0000001c
PROCESS_NAME: lec_teacher.exe
READ_ADDRESS: 0000001c
ERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%p 0x%p %s
EXCEPTION_CODE_STR: c0000005
EXCEPTION_PARAMETER1: 00000000
EXCEPTION_PARAMETER2: 0000001c
STACK_TEXT:
00cf8dec 002da5ca 96b6b062 3951c6b0 40f28218 lec_teacher!GoodsPreviewWidget::getShowMode
00cf8e38 66a0c9ba 00000001 3951c6b0 1e7cb010 lec_teacher!GraphicsToolManager::onCountDownAccepted+0x7a
00cf8ed0 66a0cc8e 40f26bc8 66d48844 66d48844 Qt5Core!QMetaObject::activate+0x40a
https://docs.microsoft.com/zh-cn/windows-hardware/drivers/debugger/general-extensions
拖动打开:可以直接将dump文件拖动到窗口中,就可以打开。
操作打开:文件- start debugging- open dump file
快捷键:Ctrl + d
命令:. opendump (打开转储文件)
在命令提示符窗口中(cmd):windbg-y SymbolPath -i ImagePath -z DumpFileName
加载一般需要一段时间,稍微等一下就ok。
在打开dump文件之后,很重要的事情就是设置符号文件(pdb)
要控制 WinDbg 中的符号路径,请执行以下操作之一:
1、命令(元命令):使用 . sympath (设置符号路径) 命令。 如果使用的是符号服务器,则 symfix (设置符号存储路径) 命令类似于 . sympath ,但会保存键入内容。
2、界面操作:home - setting -debugging settting 如下图
完成前面2步就可以开始调试崩溃信息,在打开dump文件时候,有一个提示,可以点击操作,命令(扩展命令)是!analyze -v 如下图
!analyze -v 是继承了很多的操作,在一开始命令分类中就介绍了,例如:
(.ecxr) , (.exr -1), ~0s ; .ecxr ; kb
虽然!analyze -v虽然帮助我们综合的显示了一下崩溃信息,但是我们还是需要了解一些基本的操作指令,第一个就是查看调用栈
查看调用栈的命令是 k
0:000> k
# ChildEBP RetAddr
00 00cf8434 754d1f23 ntdll!NtWaitForMultipleObjects+0xc
01 00cf85c8 754d1dd8 KERNELBASE!WaitForMultipleObjectsEx+0x133
02 00cf85e4 7773ebc0 KERNELBASE!WaitForMultipleObjects+0x18
03 00cf8690 7773eddf kernel32!WerpReportFaultInternal+0x3b7
04 00cf86ac 77701319 kernel32!WerpReportFault+0x9d
05 00cf86b4 755660f2 kernel32!BasepReportFault+0x19
06 00cf8754 77abd511 KERNELBASE!UnhandledExceptionFilter+0x2a2
07 00cffd1c 77a8302a ntdll!__RtlUserThreadStart+0x3a4e6
08 00cffd2c 00000000 ntdll!_RtlUserThreadStart+0x1b
或者可以在stack的窗口中看到调用栈,如果想查看不同层级的帧,可以点击对应的函数方法就可以。堆栈跟踪基于当前线程的堆栈。
~ s 命令设置或显示当前的线程号。~线程的操作命令
~Thread s ,Thread 表示第一个线程。
~ 线程的状态
命令 | 操作 |
~ | 显示所有线程。 |
~* | 显示所有线程。 |
~. | 显示所有active 的线程 |
~# | 引起异常的线程 |
~2 | 显示2号线程 |
0:000> ~
. 0 Id: 390.4418 Suspend: 0 Teb: 00b7b000 Unfrozen ""
1 Id: 390.42f8 Suspend: 1 Teb: 00b87000 Unfrozen
# 2 Id: 390.4174 Suspend: 1 Teb: 00b8a000 Unfrozen ""
3 Id: 390.3ffc Suspend: 1 Teb: 00b8d000 Unfrozen
在此输出的第一行,0是小数线程号,390 是十六进制的进程 ID,4418是十六进制线程 ID,0x7FFDE000 是 TEB 的地址,而 解冻 的是线程状态。
在线程1之前 . 这意味着此线程为当前线程。
线程2前面的数字符号 (#) 意味着此线程最初引发异常,或者在调试器附加到进程时它处于活动状态。
未完待续