如何在进程创建的过程中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了!
祝你debugging愉快~
翻译自:
How to attach a debugger from the creation time of the Worker Process (w3wp.exe)