If you’ve ever used Debugging Tools for Windows, you’ve probably used remote debugging. Users of windbg/ntsd are usually familiar with the “.server” command and connecting to remote debugging sessions using “Connect to Remote Session” in windbg. Knowing this, what good is the dbgsrv utility that comes with the Debugging Tools for Windows? How is it different from a normal remote debugging session?
For anyone familiar with dbgsrv, it is similar in purpose and function to msvsmon, the visual studio remote debugging monitor. Both applications are “process servers” for their respective debugging environment. Running dbgsrv on a remote machine allows developers to attach to any process on that machine, or launch processes under the debugger.
Using dbgsrv is slightly mysterious, as the UI for using it is a bit cryptic in WinDbg. I’m going to run through a few examples to show how useful dbgsrv can be.
To start, we need to get dbgsrv running on the machine you want to debug. Usually, this will be a test computer that you want to debug from your development computer. If you want to follow along the examples, you can use a single machine, although this scenario isn’t very useful for real world debugging. To start dbgsrv, run it from the command line giving it parameters to pick a transport to use. Usually, tcp is the easiest when not working with domain-joined machines:
dbgsrv -t tcp:port=31337
If there are no errors, dbgsrv will start silently and start listening for connections. (You may see a firewall dialog at this point). To use the process server from windbg, use the “Connect to Remote Stub…” menu item from the File menu:
The connection string should match what you’ve started dbgsrv with. For instance, if dbgsrv is running on my computer named “timtst”, I would connect to “tcp:port=31337,server=timtst”. After accepting the connection string in this dialog, there will be no indication of failure or success until you actually try to use it. Once the connection string is entered, you can try to attach to a process using File->Attach to Process, or using F6. If the connection was successful, you will see a list of processes on your test computer, or an error if the connection was not successful.
To use the same functionality in cdb/ntsd, you can use the “premote” command line argument. For instance, to use the same dbgsrv instance as in the previous example to attach to process ID 4000, you can use the following command with ntsd:
ntsd -premote tcp:port=31337,server=timtst -p 4000
Using ntsd also lets you start a process under the debugger through a process server:
ntsd -premote tcp:port=31337,server=timtst C:\MyTestApp.exe
Note that the path given refers to a path on the remote machine running dbgsrv, not the machine running ntsd. This functionality is not available in windbg.
There is an excellent write-up with more information about dbgsrv at nynaeve.net
If you’ve found this interesting, I highly recommend the book Advanced Windows Debugging
by Daniel Pravat. As one of the most informative books about the Windows Debugging toolset, it has a host of information about dbgsrv and the rest of the tools.