Moving onwards to the more modern remote debugging services available, the next option available for remote debugging with the DTW package is -server/-remote.  This remote debugging mechanism is one that you may find yourself using fairly frequently. Its advantages are rich functionality and integration with the WinDbg GUI (as a remote client), and reasonably low bandwidth usage, though not quite as lightweight as the previous options.
This mechanism allows you to connect one (or more) debugger clients to a debugger server. This can allow for a limited set of collaboration between multiple people debugging the same problem. Unlike the other mechanism discussed thus far, -server/-remote utilizes a more advanced protocol that while leaving most of the “hard work” (including symbol management) to the debugger server, allows things like the various WinDbg debuggee status windows to work and receive useful information (i.e. not just command window text). So, when using this protocol with WinDbg as the client, you can utilize the memory / disassembly / register windows (and soforth). Note that you can use any of WinDbg/ntsd/cdb/kd as either a client or server with this protocol. It can be used for any debugging type that is supported by these debuggers, including dump file debugging.
The protocol also provides for varying forms of security. You can use simple plain text password authentication, or if you want true security, SSL over named pipes or TCP. The protocol can operate over several underlying transports; tcp, com (serial port), 1394, or named pipes (note that this is the transport used to communicate between the debugger server and debugger client, not related to the medium that is used to connect to the target in kd).
When using -server/-remote, it is important to ensure that both the debug client and debug server are from the same DTW package; otherwise, unexpected results may occur (typically resulting in the connection failing silently).Â
There are many different ways to activate this remote debugging mechanism; you can start a debugger with -server to create a debugger server, or with -remote to act as a debugger client. Alternatively, you can use the .server command to create a debugger server out of an existing debugging session. If you are using WinDbg, you can use File->Connect to Remote Session (Shortcut: Ctrl-R) to connect to a remote debugging server instead of using the -remote command line parameter.
To use this debugging mechanism, you will need to create a connection string to be used by the debugger server and then the debugger client. The general format of a connection string is “transport:transport-parameters”. For our examples, I will use tcp as the transport; this is likely to be the most common you’ll use in the real world. You can look up the usage of the other transports in the documentation if you are curious.
A simple connection string to use if you want to create a tcp server that listens on port 12345 would be “tcp:port=12345”. The client connection string corresponding to this would be “tcp:port=12345,server=ip_or_hostname_of_server”. (Note that if you are using the DTW 6.6.3.5 package, then it is required that you specify port= before server= in the client connection string or the connection will fail, due to a parser bug in the debugger). If you use the “.server tcp:port=12345” command, you’ll see something like this:
0:001> .server tcp:port=12345
Server started. Client can connect with any of these command lines
0: -remote tcp:Port=12345,Server=COMPUTERNAME
Then, you can connect to it using WinDbg and specifying either “tcp:port=12345,server=localhost” (assuming you are running on the same computer) to either the Ctrl-R/Connect to Remote Session dialog or the -remote parameter:
Microsoft (R) Windows Debugger Version 6.6.0007.5
Copyright (c) Microsoft Corporation. All rights reserved.
Server started. Client can connect with any of these command lines
0: -remote tcp:Port=12345,Server=COMPUTERNAME
COMPUTERNAME\User (tcp 127.0.0.1:2025) connected at Mon Jul 24 01:33:20 2006
On the server, you’ll see a notice that someone has connected:
COMPUTERNAME\User (tcp 127.0.0.1:2025) connected at Mon Jul 24 01:33:20 2006
Henceforth, all output will be sent to all clients and the local server text output. Additionally, clients will be able to use the debuggee status UI windows (e.g. disassembly) as well as viewing command output text. After all this is setup, then you can continue to debug as if you were on the server computer (keep in mind, however, that symbol paths are relative to the server and not the client computer). If you connect multiple clients to the same session, then each additional client will be updated as any debugger client changes the state of the debugging session.
That’s a quick overview of -server and -remote. However, there’s a bit more to this particular remote debugger mechanism than what I have talked about so far. I’ll elaborate on some other features and usage cases of -server and -remote in the next post in this series.
[…] Previously, I’ve discussed the basics of -server and -remote, and how to do reverse debugging connections. This covers most of the interesting functionality for this remote debugging mechanism, with one big exception: securing your remote debugger connection when you are operating over an untrusted network (such as the Internet). […]
[…] Most of the debugging mechanisms I have gone through so far will also support kernel debugging, though I have not focused on this fact. You can use remote.exe for controlling KD remotely, and -server/-remote for controlling one KD through another KD or WinDbg. Both of these mechanisms can be used to control a kernel debugger remotely (keep in mind that you still need a separate computer to run kd.exe on from the target computer of course), however, they do not allow the same flexibility as dbgsrv.exe does. This means no client-side symbol access, and no client-side debugger extensions. […]
[…] Remote debugging with -server and -remote […]