Remote debugging review

Over the past week or two, I’ve written about some of the various remote debugging options available to you through the Debugging Tools for Windows (DTW) package.  I’ve covered most of the major debugging mechanisms available at this point and given brief descriptions of their strengths and weaknesses.

Here’s an indexed listing of the posts on this topic so far:

  1. Overview of WinDbg remote debugging
  2. Remote debugging with remote.exe
  3. Remote debugging with KD and NTSD
  4. Remote debugging with -server and -remote
  5. Reverse debugging -server and -remote
  6. Securing -server and -remote remote debugging sessions
  7. Remote debugging with process servers (dbgsrv)
  8. Activating process servers and connecting to them
  9. Remote debugging with kdsrv.exe
  10. Remote debugging review

At this point, you should be able to use all of the above remoting mechanisms in their basic usage cases.  There are a couple of obscure features that I did not cover, such as doing -server/-remote over serial ports, but between my posts and the documentation you should be able to figure out what to do if you ever find a use for such estorica (let me know if you do!).  What remains to be told is some general advice on which remoting mechanism is the best for a particular problem.

In general, the most important factors in choosing a remoting mechanism are:

  • Available bandwidth and latency between your computer and the remote system.  Some remoting mechanisms, like dbgsrv, perform very poorly without a high bandwidth, low latency link.
  • Whether symbol access needs to be done on the client or the debugging target.  This consideration is important if you are debugging a problem on a customer site.
  • What types of targets you need to support.  Some mechanisms, such as process servers, do not support all target types (for instance, lack of dump file debugging support).
  • Whether you need special support for working through a firewall (i.e. reverse connection support).
  • Ease of use with respect to setting up the remoting session.

These are the general factors I use to decide which remoting mechanism to use.  For example, in ideal cases, such as debugging a problem on a LAN or on a virtual machine hosted on the same computer, I will almost always use a process server for remote debugging, simply because it lets me keep my own WinDbg workspace settings and symbol access without having to set up anything on the target computer.  Over the Internet, process servers are usually too slow, so I am often forced to fall back to -server/-remote style remoting.

Taking into account the guidelines I mentioned above, here are the major scenarios that I find useful for each particular remoting mechanism:

  • Process servers and smart clients (dbgsrv).  This is the remote debugging mechanism of choice for remotely debugging things on virtual machines, on a LAN or other fast connection, or even on the same computer (which can come in handy for certain Wow64 debugging scenarios, or cross-session debugging under Terminal Server prior to Windows XP).  Process server debugging is also useful for debugging early-start system services remotely, where the intrastructure to do symbol access (which touches many system components, for things like authentication support) is not yet available – for this scenario, you can use the “-cs command-line” parameter with dbgsrv to start a target process suspended when you launch dbgsrv, which is handy for using Image File Execution Options to have dbgsrv act as a debugger for early start services.  This can be more reliable than -server and -remote if you are trying to do symbol access, as if you are debugging certain services, you might deadlock the debugger and lose the debugging session if the debugger has to talk to the service you are debugging in order to complete a network symbol access request.
  • -server and -remote.  If I am doing debugging over the Internet, I’ll usually use this mechanism as it’s relatively quick even over lower quality connections.  This mechanism is also useful for collaborating with a debugging session (for instance, if you want to show someone how to perform a particular debugging task), as you can have multiple users connect to the same debugging session.  Additionally, -server/-remote are handy if you have a large dump file on a customer site and you want to debug it remotely instead of copying it to your computer, but would like to do so from the context of your local computer so that you have easier access to source code and/or documentation.  Finally, -server/-remote support remote kernel debugging where process servers do not.
  • KdSrv.exe.  If you need to do remote kernel debugging over a LAN, this is the mechanism of choice.  Be aware that kernel debugging is even more latency and bandwidth sensitive than process servers, making this mechanism useless unless you have a very fast, LAN-like connection to the target.  If these conditions hold true, KdSrv.exe provides the main benefits that a process server does for user mode debugging; local symbol access, local debugger extensions, and allowing the debugger to use your workspace settings on the local computer as opposed to setting up your UI on a remote system.
  • NTSD through KD.  This is useful in a couple of specialized scenarios, such as debugging very early start processes or performing user mode debugging in conjunction with the kernel debugger.  While controlling NTSD through KD is much less convenient than through a conventional remote debugging session, you won’t have to worry about your session going away or getting disconnected while the remote system is frozen in the kernel debugger.  In particular, this is useful for doing things like debugging things that make calls to the LSA from kernel mode, or other situations where kernel mode code you are debugging is extensively interacting with user mode code.
  • Remote.exe.  I have never really found a situation that justifies the use of this as a preferred remoting mechanism, as its capabilities are far eclipsed by the other remoting services available and the benefits (low network utilization) are relatively minimal compared to -server/-remote in today’s world of cable modem and xDSL connections.

If you are debugging a problem on a customer site, you will likely find reverse connection debugging highly useful.  All of the modern remote debugging mechanisms support reverse connections except NTSD over KD, for obvious reasons.

Another consideration to take into account when selecting which mechanism to use is that you can mix and match multiple remoting mechanisms within a debugging session if it makes sense to do so.  For instance, you can start a process server, connect to it with ntsd, and launch a -server/-remote style server with “.server” that you then connect to with WinDbg.  This capability is usually not terribly useful, but there are a couple of instances where it can come in handy.

That’s all for this series on remote debugging.  I may come back and revisit this topic again in the future, but for the moment, I’ll be focusing on some different subjects for upcoming posts.

3 Responses to “Remote debugging review”

  1. dispensa says:

    Why is kdserv.exe so sensitive to bandwidth if you can do actual kd debugging over a null modem rs-232 port?

  2. Skywing says:

    In general, the kd protocol is extremely latency sensitive and you won’t be able to use it on other than a LAN – using kdsrv doesn’t really eliminate this, unfortunately. For instance, to enumerate a single process with `!process 0 0′ takes 9 separate read operations, each of which is a round trip to the target:

    WRITE: Write type 2 packet
    READ: Wait for ACK packet
    READ: Wait for type 2 packet
    KdReadVirtual(811d14bc, 80) returns 00000000, 80
    WRITE: Write type 2 packet
    READ: Wait for ACK packet
    READ: Wait for type 2 packet
    KdReadVirtual(811d15a8, 80) returns 00000000, 80
    WRITE: Write type 2 packet
    READ: Wait for ACK packet
    READ: Wait for type 2 packet
    KdReadVirtual(811d1584, 24) returns 00000000, 24
    WRITE: Write type 2 packet
    READ: Wait for ACK packet
    READ: Wait for type 2 packet
    KdReadVirtual(811d1450, 6c) returns 00000000, 6c
    WRITE: Write type 2 packet
    READ: Wait for ACK packet
    READ: Wait for type 2 packet
    KdReadVirtual(811d1438, 18) returns 00000000, 18
    WRITE: Write type 2 packet
    READ: Wait for ACK packet
    READ: Wait for type 2 packet
    KdReadVirtual(811d153c, 48) returns 00000000, 48
    WRITE: Write type 2 packet
    READ: Wait for ACK packet
    READ: Wait for type 2 packet
    KdReadVirtual(811d1628, 80) returns 00000000, 80
    WRITE: Write type 2 packet
    READ: Wait for ACK packet
    READ: Wait for type 2 packet
    KdReadVirtual(ffb1b498, 80) returns 00000000, 80
    PROCESS 811d1438 SessionId: 0 Cid: 0474 Peb: 7ffde000 ParentCid: 0144
    DirBase: 02180360 ObjectTable: e190b148WRITE: Write type 2 packet
    READ: Wait for ACK packet
    READ: Wait for type 2 packet
    KdReadVirtual(e190b184, 80) returns 00000000, 80
    HandleCount: 31.
    Image: cmd.exe

    This kind of behavior really translates into a worst-case scenario for a network protocol; lots of sequential, very small packets that results in a great deal of overhead, making a protocol that is highly dependant on low latency and uses available bandwidth relatively inefficiently.

    Even with bulk data transfers, the nature of the kd/kdsrv protocol is such that with around 90ms round trip latency, you’ll see something on the order of ~650 *bytes* per second.

    Things obviously get better as latency goes down, but you are still using bandwidth relatively inefficiently; even discounting overhead, the nature of the kdsrv protocol, with the “smarts” being on the debugger itself and not the kd connection server, many operations will require the transfer of large amounts of data (e.g. memory reads) to the debugger which eats up bandwidth quickly.

  3. bird says:

    Hi,
    I have learned how to do remote debugging. But I want to know the kernel mode debugging principal about Windows OS.Can you give some advice or other information.
    thanks.