Windbg kernel debugging over serial connection

Hi…I am burned out from trying to establish a kernel debugging connection over serial. My host is a laptop running Win 7 x64 using a USB-serial adapter on COM2 @115200 baud. My target is a desktop running Win 7 x64 with an onboard serial connector on COM2 @115200 baud. The target is set in debug mode on COM2 @115200…verified by bcdedit.


I have verified that both computers are talking over the serial connection using several serial monitors. When I set Windbg in kernel mode, on COM2@115200 Baud, it indicates a connection to COM2 but it sits there with a notice, “waiting to connect”. At this time, wdbg is frozen, no commands can be entered. If I try it with KD, I can still enter some commands.


While the KD debugger was running I entered .server then <ctrl-> enter and it spawned a debug the debugger window with cdb. By setting up a pipe using the same pipe as offered in KD, in the target in a KD window (started as KD -kl), I got communication between CDB and the target KD. The connection is very fast but the pipe is likely using the network cable. Don’t know.


When I start windbg in kernel mode and it is ‘waiting to reconnect’, I am supposed to reboot the target machine. I verified that the target is loading kdcom.dll early in the debug boot but kdcom.dll does not show up in the list of running process once debug mode reaches the desktop. kdcom.dll is listed as the 3rd driver loaded, behind ntoskrnl and HAL.


Hitting ctrl-break many times in the wdbg host does nothing.


Someone mentioned that Windows connects directly with the serial ports but that is not possible. It must go through a driver to access the serial ports and I think that’s what kdcom.dll is supposed to do. If it’s not loaded, it won’t be doing much.

gordo999 wrote:

Hi…I am burned out from trying to establish a kernel debugging connection over serial. My host is a laptop running Win 7 x64 using a USB-serial adapter on COM2 @115200 baud.

It’s a little unusual for a USB serial adapter to be assigned the names
COM1 or COM2.  There are apps that make assumptions about the standard
COM port names (1, 2, 3, 4).  Did you force that assignment, or was it
assigned automatically?

I have verified that both computers are talking over the serial connection using several serial monitors.

By that, you mean you can type characters on one system and see them
appear at the other end?  Are you using a standard cable or a null modem
(“Laplink”) cable?

While the KD debugger was running I entered .server then enter and it spawned a debug the debugger window with cdb. By setting up a pipe using the same pipe as offered in KD, in the target in a KD window (started as KD -kl), I got communication between CDB and the target KD. The connection is very fast but the pipe is likely using the network cable. Don’t know.

I’m a little confused by this description here.  Do you mean you started
KD on your target machine and spawned a server?  In that case, you
aren’t talking to the target’s kernel debugger at all. It’s just two
user-mode processes communicating.

When I start windbg in kernel mode and it is ‘waiting to reconnect’, I am supposed to reboot the target machine. I verified that the target is loading kdcom.dll early in the debug boot but kdcom.dll does not show up in the list of running process once debug mode reaches the desktop.

Right.  It’s not a process.  It’s native-mode DLL.

Someone mentioned that Windows connects directly with the serial ports but that is not possible. It must go through a driver to access the serial ports and I think that’s what kdcom.dll is supposed to do. If it’s not loaded, it won’t be doing much.

Of course it is possible.  It only talks to the standard COM ports, and
those addresses have been standardized for 35 years. They are
hard-coded.  Kdcom is not a driver in any normal sense. It is a
native-mode DLL, and ntoskrnl is statically linked to it. The operating
system will not boot if kdcom.dll is not loaded.

@Tim_Roberts said:

It’s a little unusual for a USB serial adapter to be assigned >the names

Sorry for all the black lines. In preview it shows the text merged into one blob and I am trying to add some form.


Those are the port available with the adapter in Device Manager\Ports (Com & LPT). Under Properties\Port Settings there are many variables.


On the main page I have set:
Baudrate=115200
data bits=8
parity=none
stop bits=1
flow control=hardware


I selected hardware because Microsoft lays out the wiring for a null modem cable with full handshaking. I have never found a reference to the flow control they require.


I am using a null modem cable and I have verified it is wired exactly to Microsoft specifications for serial debugging.


In Device Manager under Properties\Advanced for the adapter:

-COM ports are selectable from COM1 to COM 256. Suspecting I may have a conflict with COM2 I selected COM10 all around, including Windbg and KD. COM10 is not selectable in the kernel debug mode for Windbg but it will accept it as a command line entry. When it starts it says, Connected to \.\COM10…Waiting to connect.


-had not noticed this before but a selection in the Advanced section is listed as “USB” transfer size with Rx=4096 bytes, and Tx = 4096 bytes. That’s obviously a USB buffer and I may be overloading the Serial buffer in the adapter, or maybe it’s taking a long time to fill a 4096 byte buffer.


-another selection is BM options with a selection for ‘latency’. I lowered it to 4 sec after reading about it on the Net.


-another selection is labelled Timeouts, for read/write. I have minimum read timeout at 2000 msec and min write at 0 ms.


Under Miscellaneous Options:
-serial enumerator is ON
-serial printer is OFF
-cancel if power off is OFF
-event on surprise removal is OFF
-set RTS to off at close is OFF
-disable modem control at startup is OFF
-enable selective suspend is OFF
-selective suspend idle timeout is 5 msec.


The disable modem selection gives me an idea. I do have a modem port on the host and it is connected through an adapter module inside the laptop, obviously to a serial port.


In BIOS settings there is reference to a serial port but there is no physical port to the outside. It is enabled. I’ll try the selection to disable modem control at startup.


I have thought about going inside the laptop and removing the modem adapter to see if I have a real serial port available. However, it is not listed in Device Manager as a COM port.


-I also have a Bluetooth adapter connected to COM5 and COM7. I had no idea till recently that Bluetooth is a wifi version of RS-232. It may be possible to adapt the port it’s module uses to interface with the motherboard since it must be an RS-232 port.


Alternately, I have considered using Bluetooth itself as a serial communication device. I don’t have Bluetooth on my desktop mobo, however, and I’d need a way to devise one.


I have also thought about the Intel serial-over-LAN connection but I have to research that.

@Tim_Roberts said:> By that, you mean you can type >characters on one system and see them
appear at the other end? Are you using a standard cable >or a null modem

Have to learn to use Markdown formatting.

Yes…I have used Putty to write both ways between Putty instances on the host and target. I also have a couple of serial monitors and I can see Windbg outputting the ASCII characters iiii followed by then a series of bytes. It keeps repeating that format.

In one serial monitor I can test the hardware handshake and all lines seem to be working.

Tim…re Kdcom.dll…Right. It’s not a process. It’s
native-mode DLL.

I’m confused about that. If I open kdcom.dll in IDA, I see functions like:
KdDebuggerInitialize0
KdpReceiveString
KdpSendControlPacket
KdReceivePacket
CpSetBaud
CpGetByte
CpWritePortUchar
CpWriteRegisterUchar
and so on. Seems to me it’s playing a vital role in interfacing the target debug session to the host debugger.

It imports function from ntoskrnl and HAL like KdDebuggerNotPresent and KdComPortInUse.

@Tim_Roberts said:
Of course it is possible. It only talks to the standard COM >ports, and those addresses have been standardized for 35 >years. They are hard-coded.
I did not express myself accurately. I’m an old-timer who goes back to the early days of DOS and Windows. In those days, you could write directly to a port using the IN and OUT commands is DOS debug, the BASIC interpreter, and Assembly.


With Windows you can’t, they have introduced layers of abstraction between the hardware ports and the executive. As I understand it, HAL does the abstracting between the actual physical ports and ntoskrnl.


I presumed, probably incorrectly, that kdcom.dll plays a role in interpreting the serial device data and control signals via HAL. I think that because firewire uses kd1394.dll and USb uses kdusb.dll. Seems to me kdcom.dll is specifically for serial comm.


I don’t profess to be an expert on this, you are likely light years ahead of me.

@Tim_Roberts said:
I’m a little confused by this description here. Do you mean >you started KD on your target machine and spawned a >server?
No…I had KD running on the host and it was indicating a connection to \.\COM2…‘waiting to connect’.


With Windbg under the same conditions, it is not possible to enter any commands. The commands line is unresponsive.


With KD as host, in kernel mode debugging, I can enter some commands. I have experience with debuggers but I am not that proficient yet with Microsoft debuggers and I was looking for some commands that might force a response on the target, or at least give me an indication of what was wrong.


I saw a bunch of KD commands and entered ‘.server’ on a whim. Then I noticed some ctrl-key commands I could enter and I tried a few to see what would happen.


The ctrl-\ command spawned a cdb session but I had no idea what was going on. Following that command, KD gave a -remote expression, so I went to the target and started KD with 'KD -remote using the pipe expression from KD on the host


I got plenty of action then between cdb and KD on the target but I was informed later that the pipe was running over the network cable, not the serial port.


In fact, KD on the target just seemed to be echoing whatever appeared on the cdb screen.


I did try a network connection using port address 55555 but had no luck. I followed the Microsoft instruction and got a key generated but the host debugger claimed it could not find the debuggee.

On Apr 3, 2019, at 7:43 PM, gordo999 wrote:
>
> …I’m an old-timer who goes back to the early days of DOS and Windows. In those days, you could write directly to a port using the IN and OUT commands is DOS debug, the BASIC interpreter, and Assembly.
>
> With Windows you can’t,

A Windows user-mode app you can’t. Windows kernel code certainly can.

> they have introduced layers of abstraction between the hardware ports and the executive.
> As I understand it, HAL does the abstracting between the actual physical ports and ntoskrnl.

Nope. Again, the kernel debugger is special, top to bottom. It lives in the kernel and runs in privileged mode. It can – and does – use IN and OUT instructions to the same well-known I/O ports you used in MS-DOS. That’s why you can’t use a USB-serial adapter on the target system.

Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

@Tim_Roberts said:

Nope. Again, the kernel debugger is special, top to >bottom. It lives in the kernel and runs in privileged mode. >It can – and does – use IN and OUT instructions to the >same well-known I/O ports you used in MS-DOS. That’s >why you can’t use a USB-serial adapter on the target >system.

Then how would I debug the target debugger, so to speak, so that I can see where the system is getting hung up?


If I have windbg on the host claiming it is waiting for the target (debuggee it is called) to respond, and I am able to see the control messages from the host on the target via the serial port, how could I set up KD or Windbg on the target to find where those messages are going and why they are not being acknowledged?


I have my target system setup so I can access a command prompt at the logon screen. I don’t know where the debug mode process begins on the target after boot, but if I could start kd at a prompt at the logon screen, maybe I could see what is happening.


Don’t know if that is possible.

Then how would I debug the target debugger, so to speak, so that I can see where the system is getting hung up?

This is extremely difficult. The developers who own this part of the debugger debug the debugger transport basically by printf to the COM port, connected a serial console. You can try the same, although if the issue is getting the thing to even connect to windbg, then it’s likely it’ll also fail to connect to your serial console.

You can squeeze a little bit of debug data from the windbg client by pressing CTRL+ALT+D. But it’s rarely useful for debugging low-level connection issues.

The next best thing is to run the OS in a VM, and monitor the VM’s behavior.

If it’s at all possible, I’d upgrade to Windows 10 and use its built-in network transport. Not only is it more reliable, but it is several orders of magnitude faster than COM.

(started as KD -kl),

thats is not kernel debugging you have started windg / kd / in local kernel debugging mode which is a kind of snapshot dump debugging
it is not live you are viewing a stale state of current machine .

hitting ctrl+\ (having a very old windg ? around 6.1 version ?? ) this command has been superceded by ctrl+alt+\ in newer versions

this spawns a parent debugger to an exisiting instance of windbg
and it is a server any client can connect to it from any networked machine
you probably connected to this server with -remote from your target machine
this is not kernel debugging
it is a simple server client operation (user mode) and n number of clients can connect to this and all will see the operations
being repeated in thier consoles and each of the client can issue commands that will be serialised and executed one by one in server

I did try a network connection using port address 55555 but had no luck.net debugging needs windows 8.1 > as target
it wont work in win7 as target
host can be win7
and use the provide kdnet.exe to setup netdebugging

transfer the kdnet.exe / verifiedniclist to the target (usb,cd,ftp,winscp upload and download whatever)
run kdnet from and adming cmdprompt
it will says if your nic is ok for net debugging or not
if ok
simply do kdnet ip port like kdnet 192.168.x.yyy 50000
this will create a key
transfer the key to host (usb/…whatever)

run windbg -k net:port=50000 , key=xxxxxxxxxxxxxxxxxxxxxxxx
windbg will open as waiting to connect with winsock

reboot the target to connect

@“Jeffrey_Tippet_[MSFT]” said:
You can squeeze a little bit of debug data from the windbg >client by pressing CTRL+ALT+D. But it’s rarely useful for >debugging low-level connection issues.
The next best thing is to run the OS in a VM, and monitor >the VM’s behavior. …If it’s at all possible, I’d upgrade to >Windows 10 and use its built-in network transport.

Thanks for info and tips, Jeffrey. I tried your CTRL+ALT+D and got more info, as you claimed. Here are some snippets from the results:


Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

Opened \.\com2
Waiting to reconnect…
SYNCTARGET: Timeout.
Send sync break
Send Break in …
SYNCTARGET: Timeout.
Throttle 0x10 write to 0x1
Repeat…


While I was messing with it, I got:

Opened \.\com2
Waiting to reconnect…
READ: Timeout.
READ: Wait for type 7 packet
READ: Timeout.
READ: Wait for type 7 packet
READ: Timeout.
READ: Wait for type 7 packet
READ: Timeout.


On the target, I started an instance of KD. I tried it with
KD -kl, KD alone, KD -t, and KD -k comm:port=COM2, Baud=115200. All of the above while I had Windbg running on the host and the target in debug mode.


With KD -kl, I was trying to run it as a local debugger to see if it would detect anything from the host debugger. I was looking through the KD commands trying to find one that might interact with the host on COM2.


With KD by itself, I knew it would open KD in kernel debugging mode and that the two data stream would collide in a manner that would not produce a handshake. I was just curious.


With KD -k with the comm port command line, I was curious if it would detect the host as well.


I had a bit of success. When I entered .restart in the target KD, it sent this back to the host:

READ: Wait for type 7 packet
PacketType=6, ByteCount=0, PacketId=0,
READ: Recieved KD_RESET packetThrottle 0x10 write to 0x1
, send KD_RESET ACK packet


The spelling on Recieved (sic) is there’s, not mine.


finally, I tried KD -t on the target and got this on the target:

TargetInfo::CleanSystemSymbols(0x0000000000000000,0x0000000000000000) TargetInfo::CleanSystemSymbols(0x0000000000000000,0x0000000000000000) TargetInfo::CleanSystemSymbols(0x0000000000000000,0x0000000000000000)
Restarting kd transport
Opened \.\COM2
Waiting to reconnect…
READ: Wait for type 7 packet
Resync packet id …Kd sync initial break: on
Throttle 0x10 write to 0x1
SYNCTARGET: Timeout.
Throttle 0x10 write to 0x1
SYNCTARGET: Timeout.


Not sure what to make of it all. Have to research the meaning of packet 6 and packet 7.

Oh one thing that jumps out at me - 6.12.0002.633 is ancient software. I suggest trying the latest version of the debugger. (Don’t worry - the user interface hasn’t changed in 20 years; there’s no re-training or learning needed.) You can get it by installing the SDK, and from the list of features, selecting the “Debugging Tools for Windows”. (You can deselect all the other features, if you like; you don’t need any other feature to just use windbg.exe / kd.exe.)

The download page is linked below – go for the SDK link that doesn’t say “Preview” on it.

Note that the text on the first page is perhaps a little misleading – the text could be interpreted that the debugger is only for Windows 10. But that text just means that some parts of the SDK only target Windows 10. But the debugger itself works just fine both running on Windows 7, and targeting Windows 7.

Having just installed it on a spare Windows 7 machine, I see that you should be getting debugger version 6.13.0014.1618 at the time of this writing.

https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools

https://go.microsoft.com/fwlink/p/?LinkID=2033908

@“Jeffrey_Tippet_[MSFT]” said:
Having just installed it on a spare Windows 7 machine, I >see that you should be getting debugger version >6.13.0014.1618 at the time of this writing.
Jeffrey…thanks for info and links. The version I d/l’d is version 10.0.17763.132. I now have that version running on both host and target but it makes no difference.


I have tried this with the host as W7 and target as both W7 and W10. At other times, I have reversed the host and target only to realize I cannot reboot my laptop as target with the USB-serial adapter since the drivers don’t load till well after boot.


I am beginning suspect I may have issues with my laptop as host. It a HP 8440p and HP has been known to have quirky ways of implementing hardware. For one, it has a Bluetooth adapter using COM 5 and 7, and a USB Bluetooth related entity on a main USB port.

@raj_r said:
it wont work in win7 as target
host can be win7

Raj…sorry I missed your post. I eventually got a net connection between W7 as host and Win 10 target but of course it did not work with W7 as target. I’ll try your explanation with kdnet.

BTW…I used port 55555 because things looked crowded around the suggested port 50000.

The trick for me was prepping the net connections so I could ping the host and target from each other. At first, the target was set to receive its IP from the DHCP server and I changed that to something like 192.168.0.100. With the DHCP server, the IP address is typically 169.xxx.xxx.xxx.

That meant changing the IP settings under the IPv4 properties for the Local Area Connection from dynamic to static using the 192.168.0.100 IP address. I used 192.168.0.1 for the default gateway and when the first address is entered, the system automatically sets the Subnet Mask to it’s correct value.

Using ipconfig /all, I got the Ethernet IPs I needed to ping as well as the host IP for the net setup. Using arp -a from a command prompt I got a list of IP address on the LAN connection. I had to be sure the target IP showed up on the list and vice-versa from the target.


Got a serial connection going as well between W7 as host and both W7 and W10 as target. Thanks to everyone who offered advice.

Turned out to be a problem with the W7 bootloader. I had not used W10 for some time and I booted it up one day. It replaced the W7 bootloader with it’s own bootloader and when I tried the serial connection later it started working in W10.

I later tried it with W7 but during the W10 bootloader sequence I stopped it and enabled boot debugging from the boot loader prompt, forgetting I was not booting into W10 but W7. I also made W7 the preferred OS. Of course the serial session booted to the W10 logon screen. When I rebooted I got the W7 bootloader with W7 marked in debug mode. From there it booted into W7 with the W7 host Windbg in control.