How to attach a debugger from the creation time of the Worker Process (w3wp.exe)
Normally the answer for this would be as simple as use the file image execution options (through direct editing the registry or using gflags.exe from Debugging Tools For Windows) and set the “debugger” option to you preferred debugger tool and this would do the job. At least this is the way we do for troubleshooting services startup in general. There is one detail though which is the fact the services are likely loaded in a different winstation (they would have not interactivity with the desktop) and so will be loaded your debugger meaning that even though the debugger will run as it should you will not have access to it.
Well, to fix this all you need to is to go to the services mmc, navigate to the specific service’s properties, make it use the Local System account and check the checkbox that says “allow interact with the desktop” and this would fix your problem. Right, but on thing is not ok here: Worker Processes are spawned to run in background as well as services however they are not exactly services and so there is no option to “allow interact with desktop” which means your debugger will still be loaded in the background preventing you to access it from the desktop.
The solution? There is more than one for sure, but I found this one interesting. Let’s see how it goes:
Both debuggers cdb.exe and windbg.exe from Debugging Tools For Windows are able to create TCP sockets (or named pipes connection if you prefer) and listen to them so other debuggers would be able to connect to it and share the same debugging session. So I thought we could use this socket feature to create a tunnel between the winstations where our w3wp.exe and the debugger will be originally located and the desktop where we would have second debugger running (this one in foreground).
So, first things first…
Step 1: Set the file image execution options to have your first debugger attached to the worker process when it get spawned.
To do that you need to use the regedit and create the following registry key and values:
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”
This is supposing you have the Debugging Tools For Windows installed in the c:\debuggers folder.
Step 2: Automate the debugger to open a socket for future usage
Notice the “-cf” option in the cdb.exe command line above. This will tell the cdb.exe to read some initial commands from a specified file to be executed as soon as the debugger get’s attached to the process. So we need to create a text file called cmds.txt located in the c:\debuggers folder. The content of the file will be the following:
.logopen c:\debuggers\debugging.log
.server tcp:port=9999
g
Save the file. See the comments below on what each command above does from the debugger:
.logopen – opens a log file where everything happening from this debugging session will be properly logged
.server tcp:port=9999 - listen to a TCP socket on the port 9999
g – go J
Step 3: Start the application pool and make at least one request.
When the w3wp.exe process gets created you should be able to see through the task manager that now you also have a cdb.exe process running but you can’t directly access it.
Step 4: Run your second debugger and connect it to the socket.
Run the windbg.exe from Debugging Tools For Windows passing the parameter –remote from the command line like below:
Windbg.exe -remote tcp:Port=9001,Server=MYSERVER
The “MYSERVER” above should be replaced by the server’s name.
Voila!!! The windbg.exe will connect to the socket created by the cdb.exe and you will now be able to live debug your w3wp.exe from the scratch!
Have fun!