在排查服務啟動時錯誤的時候, 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)
http://blogs.technet.com/b/marcelofartura/archive/2007/08/09/how-to-attach-a-debugger-from-the-creation-time-of-the-worker-process-w3wp-exe.aspx