如何在进程创建的过程中Attach上WinDBG

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在进程创建的过程中Attach上WinDBG相关的知识,希望对你有一定的参考价值。

在排查服务启动时错误的时候, debugger会运行在后台, 我们无法与之交互. 因为服务是运行在一个不同的winstation里的, 这意味着我们不能通过desktop与它们交互. 这也意味着, 已经加载了的debugger即使在运行, 也是运行在后台, 我们无法与它交互.

解决方案是进入services.msc, 找到这个服务的属性, 让它使用local system账号运行, 然后勾选选项"allow interact with the desktop".

但是, IIS的工作者进程worker process与服务进程一样, 都是在后台诞生的, 要命的是, 我们没有机会去勾选什么allow interact with the desktop. 这意味着debugger也会在后台被加载, 我们还是无法与它交互.

解决方案不止一种, 但是下面这种比较有趣.

cdb.exe和windbg.exe都能够创建TCP sockets(或者说是named pipes connection), 然后监听它们, 这样前台的debugger就能够连接到后台被debug的进程的debugger上, 它们共享一个debugging session. 这里我们就用这种socket的特性来在后台的winstation和w3wp.exe一起的debugger和前台的debugger之间创建一个隧道.

让我们一步一步来:

第一步:
设置应用程序image的执行选项, 从而允许在这个image的实例诞生的时候, 我们的第一个debugger能够附着到worker process上.

要做到这一点, 我们需要在注册表中创建下面的键值对:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\w3wp.exe
SZ Debugger = “c:\debuggers\cdb.exe –cf c:\debuggers\cmds.txt”

这里假设, 你的Debugging Tools For Windows安装在c:\debuggers文件夹.

第二步:
配置debugger自动地开启一个socket供以后使用.

注意上面cdb.exe命令行中的 "-cf " 选项, 它会告诉cdb.exe在debugger刚刚attach到目标进程的时候, 从某个指定的文件中读取并执行一些初始化的命令. 所以我们需要创建一个叫做cmds.txt的文本文件, 把它放在c:\debuggers目录下. 这个文件的内容是像下面这样的.
.logopen c:\debuggers\debugging.log
.server tcp:port=9999
g

保存文件. 关于debugger使用的这些命令, 请查看下面的说明.
.logopen - 任何在这个debugging session中发生的事情都会记录在这个新开启的日志文件中.
.server tcp:port=9999 - 监听在9999端口上的TCP Socket.
g - 继续执行

第三步:
开启应用程序池, 并发送个它至少一个请求.

当w3wp.exe进程创建出来之后, 你就能够通过任务管理器看出来你同时还有cdb.exe也在运行, 但是你不能直接的访问它.

第四步:
运行你的第二个debugger, 并连接到Socket上.

运行WinDGB.exe, 并传递给它一个像下面命令这样的-remote参数:
Windbg.exe -remote tcp:Port=9001,Server=MYSERVER

上面的MYSERVER应该被你的机器名所取代.

搞定啦~~~ windbg.exe已经连接到有cdb.exe创建出来的socket上了, 你现在可以从头开始对你w3wp.exe进行live debug了!
参考技术A 步骤:1)打开WinDBG并将之Attach到crash的程序进程2)输入产生dump文件的命令WinDBG产生dump文件的命令是.dump,可以选择不同的参数来生成不同类型的dump文件。选项(1):/m命令行示例:.dump/mC:\dumps\myapp.dmp注解:缺省选项,生成标准的minidump,转储文件通常较小,便于在网络上通过邮件或其他方式传输。这种文件的信息量较少,只包含系统信息、加载的模块(DLL)信息、进程信息和线程信息。选项(2):/ma命令行示例:.dump/maC:\dumps\myapp.dmp注解:带有尽量多选项的minidump(包括完整的内存内容、句柄、未加载的模块,等等),文件很大,但如果条件允许(本机调试,局域网环境),推荐使用这中dump。选项(3):/mFhutwd命令行示例:.dump/mFhutwdC:\dumps\myapp.dmp注解:带有数据段、非共享的读/写内存页和其他有用的信息的minidump。包含了通过minidump能够得到的最多的信息。是一种折中方案。

WinDbg设置托管进程断点

    WinDbg的Live模式调试。.Net 托管代码 ,使用bp,bu,bm无法设置断点,也许是我不会。研究了下,托管代码有自己的命令,!BPMD 模块名 完全限定的方法名 

步骤:

1、查找进程PID,用WinDbg,Attach上

2、使用反编译工具(IL),查找需要断点的方法名,需要完全限定名。

3、根据名称,使用!name2ee  也可找到方法的完全限定名。 

4、使用!BPMD 模块名 完全限定的方法名 设置断点。这是托管代码设置断点命令。设置完成后,显示Found 1 methods in module xxx 就设置成功。

5、继续执行程序。等待断点进入。进入后,通过!CLRStack -p查看参数即可。

 

退出,而不结束进程,使用.detach命令

 

=================另一种方法打入断点,更新日期2017-08-11==================

仅使用WinDbg,不是用反射工具,从外到里,一层层查看。
1、先DumpDomain出来。  !DumpDomain 导出Domain下每个Module
2、然后DumpModule下的所有类。!DumpModule -mt 00007ffdb2d277a0 导出此Module的所有类
3、找到指定类,Dump出所有Method。!DumpMT -MD /d 00007ffdb2d288f8 导出此类的所有方法
4、打断点。!BPMD -md MethodDesc 打入断点,参数为MethodDesc地址
bl 可列出有效断点
bc * 可清除所有断点
bc N 可清除指定断点

 

 

WinDbg调试高内存的.Net进程Dump

以上是关于如何在进程创建的过程中Attach上WinDBG的主要内容,如果未能解决你的问题,请参考以下文章

WinDbg设置托管进程断点

如何手工抓取dump文件

如何手工抓取dump文件及分析

WinDBG相关

通过Windbg动态调试去捕获C++软件异常的完整过程介绍

用windbg寻找设备树根节点