WinDbg工具用法分享

符号文件(symbol)

符号文件(win 下为扩展名.pdb文件)包含大量调试用的信息,这些信息程序运行的时候不需要,但是在调试或者调查崩溃问题时非常有用,符号文件中主要包括:

  1. 全局变量
  2. 局部变量
  3. 函数名及它的入口地址
  4. 框架指针省略(Frame Pointer Omission)信息
  5. 代码的行数

如果没有符号文件,则最多只能从dump中看出模块名+偏移,如果有符号文件,则可以精确定位到崩溃行。

公有符号和私有符号(public symbol/ private symbol)

公有符号中只包含函数名和全局变量:

私有符号中包含全部信息。

如果只有公有符号,则只能看到 函数名+偏移,如果是私有符号,则可以看到完整的行号。

windows提供的符号是公有符号:http://msdl.microsoft.com/download/symbols, 需要设置符号服务器

如何设置符号文件的路径?

D:\MyLcoalSymbol;srv*D:\SymbolCache*https://msdl.microsoft.com/download/symbols

设好后 .reload

如何手动产生dump

1. 从微软网站下载工具Procdump https://docs.microsoft.com/zh-cn/sysinternals/downloads/procdump

Procdump -ma PID/ProcessName

Procdump -ma -s 5 -n 3 PID (-s是second, -n是数量)

Procdump –ma -n 3 -s 5 -c 80 ProcessName ( -c是cpu占用超过80%)

Procdump -ma -n 10 -e 1 -f NotFound w3wp.exe (设置进程如果产生某种异常则生成dump)

2.在任务管理器中手动生成:

常用命令介绍

  1. 自动分析: !analyze -v
  2. .excr 切换到崩溃的堆栈上下文
  3. k/kb/kp 查看堆栈详细信息, kd以raw style查看堆栈信息
  4. !threads 显示所有的线程堆栈 ( ~*)
  5. ~ThreadID 切换到某个线程 (~5s :进到5号线程堆栈里面(要加s !))
  6. !address -summary 查看内存概况
  7. !heap 0 检查所有的堆内存的概况,
  8. !heap -stat -h heapAddress 查看某个堆的详细信息
  9. !heap -flt r MinSize MaxSize 查看某个大小范围内的所有堆信息
  10. u/uf 反汇编代码
  11. d, da, db, dc, dd, dD, df, dp, dq, du, dw 以不同格式查看内存
  12. dt 格式化查看某数据结构
  13. r 查看当前所有寄存器的值
  14. dv 查看当前所有局部变量的名称和值

常用扩展库Mex

下载地址:https://www.microsoft.com/en-us/download/details.aspx?id=53304

  1. 先load进去: .load D:\Mex\x64\mex.dll
  2. 在指定的内存范围内搜索字符串:

!mex.strings

!mex.grep

!grep 'Feishu' !strings 00000223b6c00000 00000223b6cff000

  1. !mex.us
  2. !mex.t
  3. !mex.runaway2 -v(-a)查看占用cpu高的线程

一个小例子

  1. 下载该dump对应的符号文件, .reload

  2. 发现报个错,提示符号文件的时间戳不匹配,但是由于符号文件下载的是正确的,所以需要 .symopt + 0x40, 让windbg忽略二进制文件和pdb文件的时戳差异

  3. .ecxr 切换到出问题的堆栈上下文,kb查看堆栈:

  4. 最后一条是thread::join,翻到这个的源代码:
  5. 用uf命令反汇编join:
  6.  Join + 0x10 是 mov eax, dword ptr [esi + 4], 接下来是test,那可以基本确定出错的是joinable()访问类成员变量出错 ( MOV EAX, dword ptr [ESI + xxh] 这种一般是在访问类的某个成员变量)

这里需要访问thread类的成员变量_Thr,那有可能是此时这个thread已经被释放掉了,所以调用这个joinable出异常,由于this指针是用ecx寄存器保存,用r命令查看所有寄存器的值:(dt -b this 同样可以)

  1. 用 !address 00340066 查看这个内存的状态:
  1. 可以看出这个this指针的确是处于被释放的状态,再结合这个问题的log,就定位出是用lamda委托时,捕获了this指针,但这个this指针被销毁后这个lamda才被执行,所以crash。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值