如何手工windbg 抓取dumpp文件

6337人阅读
逆向调试(30)
在生产环境下进行故障诊断时,为了不终止正在运行的服务或应用程序,有两种方式可以对正在运行的服务或应用程序的进程进行分析和调试。
首先一种比较直观简洁的方式就是用WinDbg等调试器直接attach到需要调试的进程,调试完毕之后再detach即可。但是这种方式有个缺点就是执行debugger命令时必须先break这个进程,执行完debug命令之后又得赶紧F5让他继续运行,因为被你break住的时候意味着整个进程也已经被你挂起。另外也经常会由于First Chance Excetpion而自动break,你得时刻留意避免长时间break整个进程。所以这样的调试方式对时间是个很大的考验,往往没有充裕的时间来做仔细分析。
另一种方式则是在出现问题的时候,比如CPU持续长时间100%,内存突然暴涨等非正常情况下,通过对服务进程snapshot抓取一个dump文件,完成dump之后先deatch,让进程继续运行。然后用windbg等工具来分析这个抓取到的dump文件。
那么如何在不终止进程的情况下抓取dump文件呢?Debugging Tools for Windows里提供了一个非常好的工具,adplus.vbs。从名字可以看出,实际上是一个vb脚本,只是对cdb调试器作的一个包装脚本。
其路径与Debugging Tools for Windows的安装路径相同,使用的方法也很简单,如下所示:
adplus.vbs -hang -p 1234 -o d:\dump
其中-hang指明使用hang模式,亦即在进程运行过程中附加上去snapshot抓取一个dump文件,完成之后detach。与之对应的是-crash崩溃模式,用户先启动adplus,然后由它启动要监控的程序,在出现异常崩溃时自动生成dump文件,或者通过Ctrl-C人为发出抓取指令。但是-crash模式在抓取完成之后,被监控的进程就必须终止。因此我们在这里只选用-hang模式。
-p是要调试的进程ID,比如ASP.NET应用线程池,在Win2003下就是w3wp.exe
-o 指定要output的dump文件路径。
另外,与adplus类似的,有个UserDump工具,但是抓取用户模式的进程,而adplus则是内核模式和用户模式两者皆可。
而总所周至的Dr. Waston,则会在进程崩溃之后的自动时候抓取dump文件,一样可以用于windbg等调试器来事后分析程序崩溃时的状态。
====================
0:000& !dumpheap -stat&
No export dumpheap found&
======解决方法:
.load clr20\sos.dll,你要先执行的。sos.dll在默认的c:\windows\microsoft.net\framework\v2.....下面,你复制到c:\program files\debugging tools for windows下面的clr20目录下面(clr20是你手工创建的)&
&=======================
& 在.NET下开发时,最基本的调试方法就是使用Visual Studio的单步调试。但是对于一些特殊情况,特别是涉及到CLR内部的时候使用这种方式就达不到目的了。&
& 如果要查看运行时内存使用情况,IL代码,CLR信息等可以使用以下两种方式:&
& 1、使用VS2005 + sos.dll&
& 2、使用Windbg + sos.dll&
& 第二种方式功能更加强大,下面我就通过实际操作展示一下怎么使用这种方法得到运行时ArrayList内部的值。&
& 有人可能会说:我直接用Visual Studio的单步调试岂不是更快?当然,这个只是一个演示,通过这个演示是为以后的高级调试打下基础&
& 在操作之前,先熟悉一下基本知识:&
& A、使用VS2005 + sos.dll调试&
& 1、需要在项目-&属性-&调试-〉启用非托管代码调试&
& 2、打开调试-〉窗口-〉即时&
& 3、在即时窗口中输入 !load sos 加载调试模块&
& 4、输入其它调试语句&
& B、使用Windbg + sos.dll&
& 1、去微软的网站下载最新的Windbg&
& 2、打开Windbg在File-〉Symbol File Path ...窗口中输入 srv*c:\symbols*/download/symbols&
& 3、运行需要调试的程序,然后在Windbg中File-〉Attach to Process中选择刚才运行的程序&
& 4、在出现的Command窗口中就可以输入调试语句&
& 5、常用调试语句:&
&& lm //查看加载了哪些模块&
&& .load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll //加载调试模块&
&& ld TestClass //加载调试符号&
&& !name2ee TestClass.exe TestClass.Program.test //显示test方法相关的地址&
&& !dumpmt -md 00976d48 //得到类的成员函数详细信息&
&& !dumpil
// 显示这个方法被编译器编译之后的IL代码&
&& !dumpheap -stat //该命令显示程序中所有对象的统计信息,显示的大小是对象本身的大小,不包括对象里面值的大小&
&& !dumpheap -mt 790fcb30 //该命令显示MethodTable 790fcb30的详细信息&
&& !gcroot
//来显示一个实例的所属关系&
&& !dumpobj(do) 012a3904 //显示一个对象的具体内容,看对象里面有什么,值是什么&
&& !ObjSize 012a1ba4 //对象实际在内存中的大小&
&& !eeheap -gc //查看托管堆的情况(包括大小)&
&& !DumpArray //查看数组信息&
&& 下面就来看看具体的调试步骤:&
& 1、我们的测试代码&
& namespace TestClass&
&& class Program&
&& [STAThread]&
&& static void Main(string[] args)&
&& ArrayList list = new ArrayList();&
&& list.Add(&aaaa&);&
&& list.Add(&bbbb&);&
&& Console.ReadLine();&
& }很简单,就是一个ArrayList&
& 运行这个程序(开始执行,不调试),然后进入Windbg,Attach到这个进程&
& 2、查看所有堆栈信息&
& 0:004& !dumpheap -stat&
&& MT Count TotalSize Class Name&
12 System.Security.Permissions.SecurityPermission&
16 System.IO.TextReader+SyncTextReader&
20 Microsoft.Win32.SafeHandles.SafeFileMappingHandle&
& 7 20 Microsoft.Win32.SafeHandles.SafeViewOfFileHandle&
20 System.Text.InternalEncoderBestFitFallback&
20 Microsoft.Win32.SafeHandles.SafeFileHandle&
& 7 24 System.Collections.ArrayList&
9036 System.Object[]&
& 790fcb30
System.String&
& Total 2202 objects&
& 除了我们的ArrayList外,还有很多其它的系统信息,先不用管它&
& 3、查看我们的ArrayList的信息&
& 0:004& !dumpheap -mt 79105cd4&
&& Address MT Size&
& 012a1b88 7&
& total 1 objects&
& Statistics:&
&& MT Count TotalSize Class Name&
& 7 24 System.Collections.ArrayList&
& Total 1 objects&
& 4、查看对应地址内部实际的值&
& 0:004& !do 012a1b88&
& Name: System.Collections.ArrayList&
& MethodTable: 79105cd4&
& EEClass: 79105c28&
& Size: 24(0x18) bytes&
&& (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c\mscorlib.dll)&
& Fields:&
&& MT Field Offset Type VT Attr Value Name&
& 08df 4 System.Object[] 0 instance 012a1bb0 _items&
40008e0 c System.Int32 1 instance 2 _size&
System.Int32 1 instance 2 _version&
& 790fc35c
System.Object 0 instance
_syncRoot&
& 08e3 1c0 System.Object[] 0 shared static emptyArray&
&& && Domain:Value a1ba0 &&&
& 可以看到ArrayList的大小为2,具体的值保存在地址012a1bb0中,是一个System.Object[]类型的数组&
& 5、查看数组信息&
& 0:004& !DumpArray 012a1bb0&
& Name: System.Object[]&
& MethodTable: 7912ad90&
& EEClass: &
& Size: 32(0x20) bytes&
& Array: Rank 1, Number of elements 4, Type CLASS&
& Element Methodtable: 790fc35c&
& [0] 012a1b50&
& [1] 012a1b6c&
& [2] null&
& [3] null&
& 6、查看数组内对象的值&
& 0:004& !do 012a1b50&
& Name: System.String&
& MethodTable: 790fcb30&
& EEClass: 790fca90&
& Size: 26(0x1a) bytes&
&& (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c\mscorlib.dll)&
& String: aaaa&
& Fields:&
&& MT Field Offset Type VT Attr Value Name&
System.Int32 1 instance 5 m_arrayLength&
System.Int32 1 instance 4 m_stringLength&
& 790fe534 4000098 c System.Char 1 instance 61 m_firstChar&
& 790fcb30
System.String 0 shared static Empty&
&& && Domain:Value d81bc &&&
System.Char[] 0 shared static WhitespaceChars&
&& && Domain:Value a16f0 &&&&
====================
windbg使用小总结
【抓dump】
1、一般抓法
adplus -hang -p 3230 -quiet 抓3230 pid进程,hang模式,相当于把那个进程暂停住,取内存快照
adplus -crash -pn w3wp -quiet 抓w3wp进程,crash模式,当那个进程崩溃结束的时候自动抓取当时的内存
adplus -hang -iis -quiet 抓IIS相关进程,包括其上host的web应用,以及iis自身
2、抓window服务
4、抓蓝屏和死机的dump
电脑无故重启或者蓝屏会在C:\WINDOWS\Minidump\下保存一个minidump,但是这个minidump可用的命令很少,一般只打!analyze –v看到是哪个进程引起的,还有相关的驱动模块就基本定位问题了。
5、IIS回收的时候抓
6、计划任务抓
比如一个进程起来后不知道它什么时候会意外崩溃,可以在计划任务里用crash里抓,当那个进程意外终止的时候,cdb可以直接附加上去,抓取当时的dump,如果要抓一些会自动重启的进程,而且要抓每次重启前的dump,可以参考附录里一节。
【常用命令】
1、先path C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727,把.net路径设置为path环境变量,一遍在windbg里可以直接.load sos,而不必.load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll
2、ld demo,加载你程序的pdb文件,调试.net程序一般要把kernel32和mscorwks的符号加载上,关于这两个东西大家可以查资料,尤其是后者有哪些函数可以多了解一些。
3、在windbg的file/symbol file path对话框里输入以下文字,以便自动加载和下载符号
C:\WINDOWS\Sd:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\.sympath SRV*d:\localsymbols*/download/symbols
其中有windows、.net2.0和自动从网上下载的调试符号,注意根据自己的情况适当修改目录
【调试死锁】
1、!syncblk,查看哪些线程拿到了锁
2、~67e!clrstack 跳到某个拿到锁的线程看它正在干什么操作,迟迟不肯释放锁
3、!runaway 查看这个占有锁的线程运行了多长时间。
4、~*e!clrstack查看所有线程的托管堆栈,看看哪些是正在等待锁的,比如hang在System.Threading.Monitor.Enter(System.Object)&
5、~136s选择该线程,显示如下
0:000& ~136s eax= ebx=08deeb5c ecx=03eff0d4 edx=5570ab69 esi=08deeb5c edi=7ffd6000 eip=7c95ed54 esp=08deeb10 ebp=08deebb8 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl= ntdll!KiFastSystemCallRet: 7c95ed54
找到ecx寄存器的值,复制后ctrl+f,向上查找,会找到!syncblk的地方,如下
0:000& !syncblk Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner be4 5 1 03ee8f88 22c8 67 185e2ef0 System.Object c 3 1 dd4 49 1060d3ac System.Object c 15 1
1aa8 80 185e7704 System.Object
11428 03eff0d4 35 1 053b8fa8 169c 120 166acd98 System.Object c6b4 61 1 06bc 86 1a5bea88 System.Object
可以看到136线程等待的锁被120号线程占着不放(格式有点乱,凑合看),
6、有时候通过ecx寄存器找锁不是很确定,可以用~* kb来把所有线程堆栈打出来,然后根据!syncblk出来的同步快的值去搜索大概有多少个线程在等那个锁。因为同样是等待锁,可等的状态不一样,有的在Q里,有的锁已经升级,有的去尝试去拿锁了,所以不一定当时ecx寄存器指向那块内存,具体如何找到某个正在等待锁的线程等待的锁的内存地址,以及它正等待的这个锁被哪个线程拿着,我还没琢磨出规律来,但一般情况下,如果有其它同步对象的话,更难查。.net里用我上面说的几步就能查出锁的问题了。
【内存泄漏】
1、!dumpheap -stat看看哪些对象个数最多,占内存最大,
2、找到某个格式比较多的对象,可以看它的方法表,然后用!dumpheap -mt 66398fa4去随机找几个对象的地址
3、用!do 1e5a22bc命令去查看几个对象的状态,属性的值等,看看正常不正常
4、用!gcroot -nostacks 1e5a22bc去查看几个对象的根正常不正常,如果有些对象的根不是自己预先设计的那样,很可能被自己没想到的对象强引用了,所以GC无法回收它,就泄漏了。
【CPU百分百】
主要用几个计数器和!runaway命令,具体见以下链接
&... 7/06/03/769307.html
【线程池耗尽】
!threadpool 能看到完成端口,线程池工作线程和timer回调各占线程池的情况。
1、!eestack -short -ee查看所有重要(获取锁的,托管的,停止并允许回收的)线程的dumpstack,差不多相当于~*e!dumpstack
2、.time 可以看到进程跑了多少时间
3、!dso 查看当前线程里有哪些对象,分析内存泄漏问题也许会用到
要想很好的用windbg排查.net问题,首先要了解一些clr宿主的基础知识,以及IL的一些基础,还有简单的寄存器和汇编尝试,再就是有个好的思路,最后就是经验和对代码逻辑的理解。
【附录:写了一个自动抓dump的工具,可在程序异常退出的时候抓dump】
【使用方法】
1、先在cmd下运行以下命令确保计划任务开着
net start &task scheduler&
2、执行以下命令安排自动抓包
at 13:27 d:\myapp\autodump\processmon.exe
其中计划启动的时间和自动抓包的程序路径要根据情况设置,计划启动之前当前用户一定要注销。
【相关配置】
&appSettings&
& &add key=&adplusPath& value=&D:\MyApp\Debugging\adplus.vbs&/&&!--adplus的路径--&
& &add key=&ProcessName& value=&w3wp&/&&!--要抓dump的进程的名字,可用部分名字,不用完整的--&
&/appSettings&
using System.Collections.G
using System.D
using System.T
namespace ProcessMon
class Program
static readonly List&int& _dumpPIDs = new List&int&();
private static readonly string _processName = System.Configuration.ConfigurationManager.AppSettings[&ProcessName&];
private static readonly string _adplusPath = System.Configuration.ConfigurationManager.AppSettings[&adplusPath&];
static void Main(string[] args)
while(true)
Console.WriteLine(&..&);
ThreadProc();
Thread.Sleep(10000);
private static void ThreadProc()
foreach(Process vProcess in Process.GetProcesses())
processName
vProcess.ProcessName.ToLower();
if (processName.IndexOf(_processName) &= 0)
Console.WriteLine(&{0}-{1}&, vProcess.ProcessName, vProcess.Id);
if (_dumpPIDs.Contains(vProcess.Id))
_dumpPIDs.Add(vProcess.Id);
DumpProcessDeg d = DumpP
d.BeginInvoke(vProcess.Id, null, null);
DumpProcess(vProcess.Id);
catch(Exception ex)
Console.WriteLine(ex);
private delegate void DumpProcessDeg(int pid);
DumpProcess(int pid)
ProcessStartInfo
System.Diagnostics.ProcessStartInfo();
Info.FileName = _adplusP
Info.Arguments = string.Format(&-crash -p {0} -quiet&,pid);
Info.WorkingDirectory
Process.Start(Info);
ponentModel.Win32Exception
Console.WriteLine(&系统找不到指定的程序文件。\r{0}&,
Proc.EnableRaisingEvents =
Console.WriteLine(&外部程序的开始执行时间:{0}&,
Proc.StartTime);
Proc.WaitForExit(60000);
if(Proc.HasExited
Console.WriteLine(&由主程序强行终止外部程序的运行!&);
Proc.Kill();
Console.WriteLine(&由外部程序正常退出!&);
Console.WriteLine(&外部程序的结束运行时间:{0}&,
Proc.ExitTime);
Console.WriteLine(&外部程序在结束运行时的返回值:{0}&,
Proc.ExitCode);
===============
补充几个命令:
1、!analyze -v :用于分析挂掉线程的详细情形,错误原因。
2、!locks :列出全部资源使用情况。
3、!locks -v 0x???????? :特定地址的死锁分析。
4、!thread 0x????????:特定线程详情。
5、.thread 0x????????:转到某个线程堆栈。
本文来自CSDN博客,转载请标明出处:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1333027次
积分:13442
积分:13442
排名:第959名
原创:72篇
转载:463篇
评论:163条
(15)(7)(3)(18)(1)(20)(4)(13)(7)(12)(8)(5)(1)(4)(7)(5)(3)(8)(3)(1)(4)(4)(1)(3)(8)(5)(3)(1)(3)(3)(4)(7)(21)(3)(11)(6)(1)(2)(13)(8)(11)(6)(12)(26)(7)(16)(5)(13)(1)(2)(13)(6)(4)(8)(11)(4)(2)(9)(1)(1)(1)(3)(2)(5)(4)(3)(1)(1)(1)(6)(1)(1)(1)(3)(6)(2)(5)(2)(6)(1)(2)(3)(7)(6)(12)(1)(3)(12)(15)(5)4297人阅读
声明:转载自
在生产环境下进行故障诊断时,为了不终止正在运行的服务或应用程序,有两种方式可以对正在运行的服务或应用程序的进程进行分析和调试。
首先一种比较直观简洁的方式就是用WinDbg等调试器直接attach到需要调试的进程,调试完毕之后再detach即可。但是这种方式有个缺点就是执
行debugger命令时必须先break这个进程,执行完debug命令之后又得赶紧F5让他继续运行,因为被你break住的时候意味着整个进程也已
经被你挂起。另外也经常会由于First Chance
Excetpion而自动break,你得时刻留意避免长时间break整个进程。所以这样的调试方式对时间是个很大的考验,往往没有充裕的时间来做仔细
另一种方式则是在出现问题的时候,比如CPU持续长时间100%,内存突然暴涨等非正常情况下,通过对服务进程snapshot抓取一个dump文件,完成dump之后先deatch,让进程继续运行。然后用windbg等工具来分析这个抓取到的dump文件。
那么如何在不终止进程的情况下抓取dump文件呢?Debugging Tools for Windows里提供了一个非常好的工具,adplus.vbs。从名字可以看出,实际上是一个vb脚本,只是对cdb调试器作的一个包装脚本。
其路径与Debugging Tools for Windows的安装路径相同,使用的方法也很简单,如下所示:
adplus.vbs -hang -p 1234 -o d:/dump
其中-hang指明使用hang模式,亦即在进程运行过程中附加上去snapshot抓取一个dump文件,完成之后detach。与之对应的是
-crash崩溃模式,用户先启动adplus,然后由它启动要监控的程序,在出现异常崩溃时自动生成dump文件,或者通过Ctrl-C人为发出抓取指
令。但是-crash模式在抓取完成之后,被监控的进程就必须终止。因此我们在这里只选用-hang模式。
-p是要调试的进程ID,比如ASP.NET应用线程池,在Win2003下就是w3wp.exe
-o 指定要output的dump文件路径。
另外,与adplus类似的,有个UserDump工具,但是抓取用户模式的进程,而adplus则是内核模式和用户模式两者皆可。
而总所周至的Dr. Waston,则会在进程崩溃之后的自动时候抓取dump文件,一样可以用于windbg等调试器来事后分析程序崩溃时的状态。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:17185次
排名:千里之外
转载:12篇
(1)(1)(1)(4)(6)2012年4月 VC/MFC大版内专家分月排行榜第一
2012年5月 VC/MFC大版内专家分月排行榜第二2012年3月 VC/MFC大版内专家分月排行榜第二2011年7月 VC/MFC大版内专家分月排行榜第二2011年1月 VC/MFC大版内专家分月排行榜第二2010年12月 VC/MFC大版内专家分月排行榜第二2010年9月 VC/MFC大版内专家分月排行榜第二2010年6月 VC/MFC大版内专家分月排行榜第二2010年5月 VC/MFC大版内专家分月排行榜第二2010年4月 VC/MFC大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。捕捉崩溃,崩溃捕捉(1)
在如下的情况下需要使用这样的技巧:
1. 生产环境上出问题, 我们需要抓取dump文件, 在线下去debug.
2. 正在运行一大堆, 当其中一个崩溃的时候, 不希望在运行时干扰整个测试动作, 仅需要收集一些测试信息.
3. 问题在连接到debugger后无法重现.
简单来说, 就是你希望在对环境影响最小的前提下, 抓取尽可能多的信息.
为了满足这种需求, 最好的方式是配置 just-in-time (JIT) debugger , 让它在进程崩溃的任何时候能够: 启动, 抓取dump, 退出.
JIT debugger的基本思想是:当一个进程崩溃的时候,加载debugger, attach debugger到进程上, 以便我们弄清楚为什么会崩溃.
有注册表键值可以提供这项基本的功能, 针对托管的, 非托管的都有. 如果你的应用程序是用托管代码编写的, 你也许会问, &我的应用程序是托管代码, 为什么我要关心native code?& 即使是给你最基本的托管代码应用程序都会运行native code, 如果你的需求是收集任何crash的数据, 你将需要为这两种类型的代码设置注册表键值. 在CLR第四版中, 已经定义了带有native code的托管JIT debugger. 然而, 这个修改并不影响我这里的指导, 这里, V2 V4都适用.
我如何配置debugger?
=====================
1. 下载并安装最新的“Debugging Tools for Windows.”
&&&&&&& a. 如果你是在运行64-bit OS, 你将会需要&and&&两个版本.
&&&&&&& b. 你在机器上既可以安装整个的工具集(这很快, 安装很小), 或者你可以在一台机器上安装, 然后从安装路径拷贝&cdb.exe&到任何目标机器上.
注意, 下面的sample.reg文件假设你安装32位debugger到c:\debuggers\x86\下, 64位debugger到c:\debuggers\x64\ 下
2. 创建或配置下面的注册表键和值(如果你使用的是64位版的windows, 你还需要在Wow6432节点下配置这些值)
&&&&&&& a. 键: HKLM\Software\Microsoft\Windows NT\Current Version\AeDebug:
&&&&&&&&&&&&&&&&&&& i. 值: &Debugger&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1. 类型: String
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2. 值数据:&&path to cdb&&-pv -p %ld -c “.dump /u /ma&&dump file path\name.dmp&;.qd&
&&&&&&&&&&&&&&&&&& ii. 值:& “Auto”
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1. 类型: String
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2. 值数据: &1&
&&&&&&& b. 键: HKLM\Software\Microsoft\.NETFramework
&&&&&&&&&&&&&&&&&& i. 值: “DbgManagedDebugger&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1. 类型: String
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2. 值数据:&&path to cdb&&-pv -p %ld -c &.dump /u /ma&&dump file path\name.dmp&;.qd&
&&&&&&&&&&&&&&&&& ii. 值: &DbgJITDebugLaunchSetting&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1. 类型: DWORD(32-bit)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2. 值数据: 2
注意: 你应该根据合适的debugger的位数,&比如说, 你想要OS/CLR为64位进程崩溃加载64位的debugger, 32位的进程崩溃加载32为的debugger. 请确保你的debugger的路径是被正确地设置了的.
下面的sample.reg文件会配置机器上的cdb.exe为自动加载, 并在每个进程崩溃的时候生成一个crash dump文件. 注意文件中的关于debugger路径和dump文件存放路径的假设.
Windows Registry Editor Version 5.00
;This reg file installs just-in-time debuggers to capture a dump of all process
;crashes for the machine.
;Assumes 32-bit debugger is cdb.exe and is installed to c:\debuggers\x86\.
;Assumes 64-bit debugger is cdb.exe and is installed to c:\debuggers\x64\.
;Assumes crash dumps can be written to c:\crash_dumps\.
;Make sure all users have write access to this directory.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
&DbgManagedDebugger&=&\&c:\\debuggers\\x64\\cdb.exe\& -pv -p %ld -c \&.dump /u /ma c:\\crash_dumps\\crash..qd\&&
&DbgJITDebugLaunchSetting&=dword:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug]
&Debugger&=&\&c:\\debuggers\\x64\\cdb.exe\& -pv -p %ld -c \&.dump /u /ma c:\\crash_dumps\\crash..qd\&&
&Auto&=&1&
;The following keys are only used on 64-bit versions of Windows (note Wow6432Node).
;They can be safely created with no side-effects on 32-bit versions of Windows.
;Alternatively, you can delete the remainder of this file if you’re running a
;32-bit version of Windows.
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug]
&Debugger&=&\&c:\\debuggers\\x86\\cdb.exe\& -pv -p %ld -c \&.dump /u /ma c:\\crash_dumps\\crash..qd\&&
&Auto&=&1&
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
&DbgManagedDebugger&=&\&c:\\debuggers\\x86\\cdb.exe\& -pv -p %ld -c \&.dump /u /ma c:\\crash_dumps\\crash..qd\&&
&DbgJITDebugLaunchSetting&=dword:
这些键值有什么作用?
=====================
“Debugger” 和“DbgManagedDebugger” 的值数据基本上就是在进程崩溃的时候运行的命令行(printf格式的字符串). OS 或者 CLR 用实际值替代掉其中的格式指示符, 然后使用当前用户的崩溃进程的上下文来运行命令. 比如说, 会用崩溃的process id去替换掉 &%ld&.
在命令行中, 我指定了:
加载cdb.exel, 也就是debugger
很显然, 你必须为debugger指定正确的路径
“-pv %ld”&: 非侵入性地(仅仅是把线程暂停)挂接到崩溃的进程上(操作系统或CLR会实质上地帮你添写PID)“.dump /u /ma&&dump file path\name.dmp&”: 拿下完整的内存dump, 使用一个独一无二的名字(使用日期, 时间, 和进程ID来扩展名称), 把它保存到指定的路径
路径和文件名可以是任何你想指定的形式. 因为debugger是在崩溃的进程的上下文中加载的, 所以你要确保你指定的路径是任何用户都有权限写入的
“.kill”: 干掉目标进程, 因为你已经得到了你需要的数据.“qd”: 离开debugger
“Auto” 和“DbgJITDebugLaunchSetting”的值设定了何时加载debugger的策略规则(policy). 正如我上面写道的, 我们希望尽快地得到数据, 并继续, 所以我们不希望用户干预的介入. 比如说, 在一个服务器上, 可能不会有人登录并点击什么OK按钮. 我描述的配置会自动地为机器上的所有进程加载注册了的debugger, 而不会弹出框来让你选择(参考, 其中有关于弹这个框的更多信息). 注意, 当这些配置存在了之后, 机器上运行的所有进程在崩溃的时候都会自动地加载起debugger, 从而不会让你有机会去在&Windows Error Reporting&里呈交这个crash.
我不在乎一台机器上的绝大多数的进程, 我可以只抓取某一个进程的crash dump么?
====================
这个问题的答案取决于你OS的版本, 还有CLR的版本. 下面是规则:
对于native code来说: 你的OS必须是Vista/Server 2008 或者更高.对于managed code来说: 你的CLR的版本必须是V4(或者更高)
下面是如何配置的方法:
1. 如同上面的2.a.i 和2.b.i一样, 配置debugger键值. (AeDebug\Debugger 和.NETFramework\DbgManagedDebugger)
2. 确保AeDebug\Auto 和.NETFramework\DbgJITDebugLaunchSetting 已经被配置为自动加载(再一次强调, 参考&来查找更多信息).
&&&&&&&&&&&&&&&&&&&& a. 或者你可以删除它们Or you can delete them.
3. 创建如下的注册表键值对Create the following registry keys and values:
&&&&&&&&&&&&&&&&&&&& a. HKLM\Software\Microsoft\Windows\Windows Error Reporting\DebugApplications
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& i. 值: &Name of application executable& (e.g. “myapp.exe”)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 1. 类型: DWORD (32-bit)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 2. 值数据: 1
&&&&&&&&&&&&&&&&&&&& b. 为每一个你希望debugger自动加载的应用程序重复这个操作.
如果你更喜欢个人的控制, 你可以配置HKCU中的DebugApplications 键值对. 当这些配置生效的时候, debugger会仅为你指定的进程加载起来, 而其他进程所使用的会是普通的错误处理方式(比如说, 最默认的配置下, 会弹出一个框, 让你提交这个错误到微软去.)
下面的例子中的sample.reg文件, 会配置cdb.exe为自动加载的, 但仅仅是为HelloWorld.exe. 你可以替代HelloWorld.exe为你想要抓取dump的进程.
Windows Registry Editor Version 5.00
;This reg file installs just-in-time debuggers to capture a dump of only the
;processes listed under the [DebugApplications] key, below.
;Assumes 32-bit debugger is cdb.exe and is installed to c:\debuggers\x86\.
;Assumes 64-bit debugger is cdb.exe and is installed to c:\debuggers\x64\.
;Assumes crash dumps can be written to c:\crash_dumps\.
;Make sure all users have write access to this directory.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
&DbgManagedDebugger&=&\&c:\\debuggers\\x64\\cdb.exe\& -pv -p %ld -c \&.dump /u /ma c:\\crash_dumps\\crash..qd\&&
&DbgJITDebugLaunchSetting&=dword:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug]
&Debugger&=&\&c:\\debuggers\\x64\\cdb.exe\& -pv -p %ld -c \&.dump /u /ma c:\\crash_dumps\\crash..qd\&&
&Auto&=&0&
;The following keys are only used on 64-bit versions of Windows (note Wow6432Node).
;They can be safely created with no side-effects on 32-bit versions of Windows.
;Alternatively, you can delete the remainder of this file if you’re running a
;32-bit version of Windows.
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug]
&Debugger&=&\&c:\\debuggers\\x86\\cdb.exe\& -pv -p %ld -c \&.dump /u /ma c:\\crash_dumps\\crash..qd\&&
&Auto&=&0&
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
&DbgManagedDebugger&=&\&c:\\debuggers\\x86\\cdb.exe\& -pv -p %ld -c \&.dump /u /ma c:\\crash_dumps\\crash..qd\&&
&DbgJITDebugLaunchSetting&=dword:
;For each application you want the debugger to be auto-launched, add a row below
;similar to “HelloWorld.exe&=dword: but replacing HelloWorld.exe with
;your application .exe name.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\DebugApplications]
&HelloWorld.exe&=dword:
除了抓dump, 我还可以做更多的事情么?
=========================
关于Windows Debugger是的命令行开关的更多的信息, 可以在Debugging Tools fow Windows中包括的文档中找到. 你并没有被限制仅仅抓取dump, 你还可以执行很多debugger的自动化操作呢.
嗯, 那么究竟是什么导致了问题发生?
========================
现在, 你已经有了dump文件, 是时候来弄清楚为什么应用程序崩溃了. 对于那些已经熟悉了dump debugging的读者, 到这里你就拉出WinDBG + SOS(托管debugging的扩展组件), 并深入研究了. 但是请等一下! 如果你的应用程序运行在CLR V4上(.Net Framework 4.0), 你可以了. 我们的目标是在VS2010中, debug dump像live debug一样的体验(如同走到了断点).
针对如何debug托管代码的crash, 搜索&managed dump debugging&会返回不少结果. 一个很好的初学者去处是&(一个微软的技术支持大牛). 她有不少关于这个话题的精彩文章,
包括, 还有一些实验, 手把手的文章.
Automatically Capturing a Dump When a Process Crashes
Enabling JIT-attach Debugging
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:35987次
排名:千里之外
原创:11篇
转载:24篇
(2)(3)(4)(9)(7)(2)(3)(1)(1)(2)(3)}

我要回帖

更多关于 dump抓取工具 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信