一步一个坑 - WinDbg调试.NET程序
引言
第一次用WinDbg来排查问题,花了很多时间踩坑,记录一下希望对后面的同学有些帮助。
客户现场软件出现偶发性的界面卡死现象一直找不出原因,就想着让客户用任务管理器生成了一个dump文件发给我,我再用WinDbg看一下现线程堆栈。
找篇教程,按步骤一步一步来,应该挺简单吧。我想。
WinDbg软件版本选择
官方版本不“绿色”,最开始从第三方下了一个《WinDbg中文版(32位/64位) 6.12 独立版》v6.12.2.663
结果不管怎么尝试,加载CLR DLL的时候都提示
0:000> .cordll -u -ve -l
CLR DLL status: No load attempts
由于没经验,一直怀疑是不是自己哪里没有配置正确、操作有问题、敲键盘的姿势不对?。做了很多尝试,才意识到会不会下载的版本有问题,于是赶紧去官网下载(Debugging Tools for Windows (WinDbg, KD, CDB, NTSD))v6.3.9600.17298。果然!新的版本不会再出现这个提示! 有人说这是软件BUG。。。一口老血。。。
32位 vs 64位 该用哪个版本的WinDbg
下载的WinDbg有32和64位两个版本,该用哪个版本呢?我们可以参考这位园友的回答(一句话总结Windbg 32位版本和64位版本的选择)
他说:只有在实时用户态调试,并且调试器也在同一台64位机器上的情况下必须用64位的调试工具集。
那么我们调试dump,选择WinDbg x86应该没错了。
按套路来
因为一直失败,更换N种套路后,保留这一种:
设置符号地址
菜单|File|Symbol File Path|设置符号地址srv*c:\symbolspub*http://msdl.microsoft.com/download/symbols
(如果你还有本地符号,点击Browse... 选择路径)
打开dump文件
菜单|File|Open Crash Dump...|选择dump文件路径打开dump文件加载SOS
0:000> .cordll -ve -u -l
CLRDLL: C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscordacwks.dll:2.0.50727.8762 f:0
doesn't match desired version 2.0.50727.5485 f:0
CLRDLL: Unable to find mscordacwks_x86_x86_2.0.50727.5485.dll by mscorwks search
CLRDLL: Unable to find 'mscordacwks_x86_x86_2.0.50727.5485.dll' on the path
CLRDLL: Unable to get version info for 'c:\symbolspub\mscorwks.dll\53A121FA5ae000\mscordacwks_x86_x86_2.0.50727.5485.dll', Win32 error 0n87
Cannot Automatically load SOS
CLRDLL: ERROR: Unable to load DLL mscordacwks_x86_x86_2.0.50727.5485.dll, Win32 error 0n87
CLR DLL status: ERROR: Unable to load DLL mscordacwks_x86_x86_2.0.50727.5485.dll, Win32 error 0n87
诶,出错了,从日志可以看出缺少 c:\symbolspub\mscorwks.dll\53A121FA5ae000\mscordacwks_x86_x86_2.0.50727.5485.dll
文件。
这个文件从哪来?
1)客户计算机:NET2.0 x86 在 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
路径下的 mscordacwks.dll
,其他版本类似;
2)从网络下载:这里有好心人已经打包了:Mscordacwks/SOS debugging archive;
把下载的文件重命名一下放到 c:\symbolspub\mscorwks.dll\53A121FA5ae000\mscordacwks_x86_x86_2.0.50727.5485.dll
路径下,这个路径就是前面设置的符号地址的存储路径。一定要确保版本完全一致,再加载一次就OK了。
加载成功后提示类似:
0:000> .cordll -u -ve -l
CLRDLL: C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscordacwks.dll:2.0.50727.8762 f:0
doesn't match desired version 2.0.50727.5485 f:0
CLRDLL: Unable to find mscordacwks_x86_x86_2.0.50727.5485.dll by mscorwks search
CLRDLL: Unable to find 'mscordacwks_x86_x86_2.0.50727.5485.dll' on the path
CLRDLL: Unable to get version info for 'c:\symbolspub\mscorwks.dll\53A121FA5ae000\SOS_x86_x86_2.0.50727.5485.dll', Win32 error 0n87
Cannot Automatically load SOS
CLRDLL: Loaded DLL c:\symbolspub\mscorwks.dll\53A121FA5ae000\mscordacwks_x86_x86_2.0.50727.5485.dll
CLR DLL status: Loaded DLL c:\symbolspub\mscorwks.dll\53A121FA5ae000\mscordacwks_x86_x86_2.0.50727.5485.dll
如果一切正常,这时候输入 !threads 就可以看到托管线程了。
0:000:x86> !threads
ThreadCount: 22
UnstartedThread: 0
BackgroundThread: 20
PendingThread: 0
DeadThread: 1
Hosted Runtime: no
PreEmptive GC Alloc Lock
ID OSID ThreadOBJ State GC Context Domain Count APT Exception
0 1 7c0 000000000077d1d0 6020 Enabled 0000000000000000:0000000000000000 0000000000778c20 0 STA
2 2 260 000000000078bfe0 b220 Enabled 0000000000000000:0000000000000000 0000000000778c20 0 MTA (Finalizer)
5 4 fd0 00000000007ec5a8 80a220 Enabled 0000000000000000:0000000000000000 0000000000778c20 0 MTA (Threadpool Completion Port)
balabala...
好事多磨
没有坑是不可能滴,我电脑上却提示:
0:000> !threads
Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
2) the file mscordacwks.dll that matches your version of mscorwks.dll is
in the version directory
3) or, if you are debugging a dump file, verify that the file
mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
4) you are debugging on the same architecture as the dump file.
For example, an IA64 dump file must be debugged on an IA64
machine.
You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll. .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.
If you are debugging a minidump, you need to make sure that your executable
path is pointing to mscorwks.dll as well.
再用.cordll和.chain检查一下SOS的加载情况
0:000> .cordll
CLR DLL status: Loaded DLL c:\symbolspub\mscorwks.dll\53A121FA5ae000\mscordacwks_x86_x86_2.0.50727.5485.dll
0:000> .chain
Extension DLL search Path:
balabala。。。
Extension DLL chain:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos: image 2.0.50727.8762, API 1.0.0, built Wed Apr 05 11:41:39 2017
[path: C:\Windows\Microsoft.NET\Framework\v2.0.50727\sos.dll]
balabala。。。
可以看到sos正常加载了啊,难道没有?哪里还有问题?。。。这里我又卡了很久没有头绪。。。
Google半天才意识到,会不会是抓的dump有问题,再查,才发现有人建议用64位任务管理器抓64位进程的dump,32位任务管理器抓32位进程的dump。我去,又是一口老血。。。
64位系统怎么抓dump
我们以抓32位进程的dump为例,先打开32位任务管理器(C:\Windows\SysWOW64\taskmgr.exe
)
确保taskmgr.exe 后面有一个*32
,表示这是一个32位程序跑在64位系统上,叫做wow64模式。
然后右键你的目标进程,点击“创建转储文件”,成功后会提示dmp文件存储路径。
也就是说,你的目标进程有 *32
,taskmgr也要有 *32
,如果没有则都必须没有。
另外:推荐抓dump工具:ProcDump 小巧又强大,里面也是区分一个32位版本和一个64位版本。
正确的dump抓下来,再按照前面的方法正常情况就可以开始分析了。
再接再励
那是不是64位任务管理器抓32位进程的dump就没用了呢?等现场抓下一个dump不知道要等到什么时候。继续Google,终于找到关键字 Debugging WOW64
然后找到这篇文章 Debugging a 64-bit dump of a 32-bit managed process
简单说,就是前面步骤做完后,通过下面两条指令切换到32bit模式
0:000> .load wow64exts
0:000> !sw
Switched to 32bit mode
切换32bit模式后后 !clrstack
可以执行,却看不到正确的堆栈信息
0:000:x86> !clrstack
OS Thread Id: 0x7c0 (0)
Failed to start stack walk: 80070057
Google无果。不过还好,可以用其他指令指令替代它,比如 !dumpstack -ee
0:000:x86> !dumpstack -ee
OS Thread Id: 0x7c0 (0)
TEB information is not available so a stack size of 0xFFFF is assumed
Current frame:
ChildEBP RetAddr Caller,Callee
002dca68 6a27d6b4 (MethodDesc 0x69e47600 +0x70 System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(System.Data.OleDb.tagDBPARAMS, System.Object ByRef))
002dca88 6a27d6b4 (MethodDesc 0x69e47600 +0x70 System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(System.Data.OleDb.tagDBPARAMS, System.Object ByRef))
002dcab4 6a27d519 (MethodDesc 0x69e475e4 +0xbd System.Data.OleDb.OleDbCommand.ExecuteCommandText(System.Object ByRef))
002dcaf0 6a27d437 (MethodDesc 0x69e475d8 +0x3b System.Data.OleDb.OleDbCommand.ExecuteCommand(System.Data.CommandBehavior, System.Object ByRef))
002dcb00 6a27d192 (MethodDesc 0x69e475cc +0xa2 System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(System.Data.CommandBehavior, System.String))
..balabala...
至此,我想看的线程堆栈信息终于出来了~~~ 额,WTF,又是万恶的ACCESS惹的祸! 再吐一口血,卒。。。
总结一下
- 最好从官方下载程序(即便它不是绿色版,即便它还和其他程序绑定
一步一个坑 - WinDbg调试.NET程序的更多相关文章
- WinDBG调试.NET程序示例
WinDBG调试.NET程序示例 好不容易把环境打好了,一定要试试牛刀.我创建了一个极其简单的程序(如下).让我们期待会有好的结果吧,阿门! using System; using System.Co ...
- WinDbg调试托管程序环境问题总结
基本环境搭建及安装 安装 有2个方式可以安装WinDbg. 新版 安装WinDbg Preview 在商店里搜WinDbg直接就可以安装,这里安装的版本是x64版本.x64版本的WinDbg其实是可以 ...
- WinDbg调试.NET程序入门
俗话说:万事开头难! 自从来到新公司遇到性能问题后,需要想办法解决这个问题,但是一直没有合适的性能分析工具,然后找到StevenChennet 大神帮忙,他用WinDbg工具远程帮我分析了一个 dum ...
- WinDbg 调试.net程序
WinDbg支持以下三种类型的命令: · 常规命令,用来调试进程 · 点命令,用来控制调试器 · 扩展命令,可以添加叫WinDbg的自定义命令,一般由扩展dl ...
- Windows调试学习笔记:(二)WinDBG调试.NET程序示例
好不容易把环境打好了,一定要试试牛刀.我创建了一个极其简单的程序(如下).让我们期待会有好的结果吧,阿门! using System; using System.Collections.Generic ...
- windbg调试.net程序
1. 解决线上.NET应用程序的如下问题: 崩溃 CPU高 程序异常 程序Hang死 2. 安装WinDbg: http://msdn.microsoft.com/en-us/windows/hard ...
- (七)使用jedis连接单机和集群(一步一个坑踩出来的辛酸泪)
环境准备: redis-4.0.9,最新版了 ruby:redis-x.x.x.gem 这个gem什么版本都行,我redis4用3.0.0的gem正常跑 jedis-2.9.0.jar,最新版 ...
- 转:windbg调试堆
转:http://www.cnblogs.com/dsky/archive/2013/05/15/3079363.html 简评: 代码中采用malloc/free进行堆申请,实际调用的仍然是Heap ...
- WinDbg调试.NET
WinDbg调试.NET程序入门 俗话说:万事开头难! 自从来到新公司遇到性能问题后,需要想办法解决这个问题,但是一直没有合适的性能分析工具,然后找到StevenChennet 大神帮忙,他用WinD ...
随机推荐
- poj 3592 缩点+SPFA
题意:给出一个矩阵,其中#代表墙,不可走,0-9代表权值,*代表可以选择传送.求从0,0点开始出发能获得最大权值. 思路:因为*的出现会有环的情况,先建图连边,将环进行Tarjan缩点,之后再从0,0 ...
- 遇到的面试题-sql
sql面试题(学生表_课程表_成绩表_教师表) 原帖链接:http://bbs.csdn.net/topics/280002741 表架构 Student(S#,Sname,Sage,Ssex) 学生 ...
- unity中object 对象之间用c# delegate方式进行通信
unity 3D经常需要设计到不同object之间数据通信和事件信息触发.这里可以利用C#本身的事件和代理的方法来实现. 这里实现了在GUI上点击按钮,触发事件,移动object cube移动的例子. ...
- C# 引用类型之特例string
在C#编程的时候经常会使用字符串(string)类型,它也是引用类型,但是处处都不作为引用的用法来使用,实属特例,下来我一一罗列出来,供自己记忆方便: 1)字符串的直接赋值:本身字符串就是引用类型,应 ...
- 2017春季 JMU 1414软工助教 链接汇总
助教自我介绍 学生博客链接和coding链接 [1414软工助教]团队博客汇总 助教总结 评分 个人作业1:四则运算控制台 结对项目1:GUI 个人作业2:案例分析 结对项目2:单元测试 团队作业1: ...
- 【2017集美大学1412软工实践_助教博客】团队作业7——Alpha冲刺之事后诸葛亮
题目 团队作业7: http://www.cnblogs.com/happyzm/p/6827853.html 团队成绩 评分项目 变更管理 设计/实现 测试/发布 团队的角色,管理,合作 总结 全组 ...
- SNS团队Beta阶段第三次站立会议(2017.05.24)
1.立会照片 2.每个人的工作 成员 今天已完成的工作 明天计划完成的工作 罗于婕 辅助完善生词本 辅助完成生词本功能 龚晓婷 辅助开发历史记录功能 辅助完善历史记录功能 林仕庄 开发历史记录功能 完 ...
- 个人作业二——英语学习APP 案例分析
英语学习APP的案例分析 我们生活中很多时候要和软件打交道,大家上课开小差时候玩的手机游戏,买火车票的网站,互相联系用的微信.QQ,等等都是软件,都很值得分析.你为何成为它们的用户?它们的团队做对了什 ...
- 团队作业4——第一次项目冲刺(Alpha版本)4.25
团队作业4--第一次项目冲刺(Alpha版本) Day four: 会议照片 每日站立会议: 项目进展 今天是项目的Alpha敏捷冲刺的第四天,先大概整理下昨天已完成的任务以及今天计划完成的任务.今天 ...
- 201521123007《Java程序设计》第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...
- WinDBG调试.NET程序示例