1. Windbg生成dump文件
程序崩溃(crash)的时候, 为了以后能够调试分析问题, 可以使用WinDBG要把当时程序内存空间数据都保存下来,生成的文件称为dump 文件。 步骤:
1) 打开WinDBG并将之Attach 到crash的程序进程
2) 输入产生dump 文件的命令
WinDBG产生dump 文件的命令是 .dump ,可以选择不同的参数来生成不同类型的dump文件。
选项(1): /m
命令行示例:.dump /m C:\dumps\myapp.dmp
注解: 缺省选项,生成标准的minidump, 转储文件通常较小,便于在网络上通过邮件或其他方式传输。 这种文件的信息量较少,只包含系统信息、加载的模块(DLL)信息、 进程信息和线程信息。
选项(2): /ma
命令行示例:.dump /ma C:\dumps\myapp.dmp
注解: 带有尽量多选项的minidump(包括完整的内存内容、句柄、未加载的模块,等等),文件很大,但如果条件允许(本机调试,局域网环境), 推荐使用这中dump。
选项(3):/mFhutwd
命令行示例:.dump /mFhutwd C:\dumps\myapp.dmp
注解:带有数据段、非共享的读/写内存页和其他有用的信息的minidump。包含了通过minidump能够得到的最多的信息。是一种折中方案。
选项(4): /f
命令行示例: .dump /f C:/dump.dmp
注解: 其中.dump是dump生成命令,/f是生成全信息dump
2. Windbg分析dump
2.1 查看线程相关
(1)、 ~ 命令是用来切换目标线程
~ 可以显示线程的信息
~0s 把当前的线程切换到0号线程,也就是主线程,切换后提示符会变为0:000.
(2) 、~* 命令列出当前进程中的所有线程的详细信息
(3)、~*kb 命令列出所有线程的堆栈
2.2查看内容相关:
(1)dd + address: 将内存地址中内容以四字节为单位显示出来
(2)da : 将内存中内容,以ascii码的形式显示出来,主要用于观察字符串
(3)du : 将内存中内容以unicode码形式显示出来,也用于显示字符串
(4)dv: 不用加内存地址,显示当前栈上面的所有的变量
(5)dt+ 格式 + (address): 把内存地址所在的内容,以制定的格式显示出来,这个格式一般是结构体等。
(6)dds: 把制定地址开始的内容,列出来,如果能对应到代码符号,将符号显示出来。
3、 Windbg 调试程序
3.1 打开windbg客户端,设置环境
1、设置Symbol File Path ...... ##符号路径,即PDB路径(windows下)。
2、设置Source File Path ...... ##源码路径。
3、File->Open Executable...... ##可执行文件(windows下),此步骤需要在同样的界面配置可执行文件的运行参数。
3.2 windbg客观端,使用命令启动调试
1、客户端,命令行调试的界面。
2、windbg命令行处使用 bp main 在main函数处设置断点。
3、windbg命令行处使用 g 开始运行程序,相当与VS下F5的效果。
4、在3步骤后,程序会在main函数处停下(即已经停在相应的代码处),然后可以在代码中使用:
F9:设置断点,只要在光标定位的位置(上图中灰色条)按F9键即可,再按一次F9键则会删除断点。(相当于OllyDbg 中的 F2)
F10:单步步过。每按一次这个键执行一条反汇编窗口中的一条指令,遇到 CALL 等子程序不进入其代码。(相当于 OllyDbg中的 F8)
F8 or F11:单步步入。功能同单步步过(F10)类似,区别是遇到 CALL 等子程序时会进入其中,进入后首先会停留在子程序的第一条指令上。(相当于 OllyDbg 中的 F7)
F7:运行到选定位置。作用就是直接运行到光标所在位置处暂停。(相当于 OllyDbg 中的 F4)
Shift+F11:运行到跳出函数。
F5:运行。按下这个键如果没有设置相应断点的话,被调试的程序将直接开始运行。(相当于 OllyDbg 中的 F9)
3.3 windbg可发现程序的死循环
1、用windbg调试的过程中,如果发现程序死循环了,需要选 break 掉程序(windbg的工具栏某个下拉选项中有),然后使用命令
~*kv ##查看所在线程,即可看到程序死循环处
or
!runaway ##查看各个线程的消耗程度
(1)使用 !runaway 后便可看到类似的结果:
User Mode Time
Thread Time
5:17c 0 days 0:02:47.373
6:530 0 days 0:00:01.154
4:188 0 days 0:00:01.123
0:72c 0 days 0:00:00.031
(2)使用命令~5 s 切换到17c线程空间(5 以及17c指上面的示例)。