Debugging user-mode apps through remote kd
Kapil Kapre | Friday, January 15, 2010

This is fairly trivial in hindsight, but I didn't find the help of any use when I was stuck debugging an user mode app through remote kd. BTW, I hope you're familiar with console debuggers because there doesn't seem to be a way to leverage any of windbg's GUI features over a remote kd session.

Once you've got kd running and connected to the target, make sure the usermode app is running. Break into KD to quickly get the process id in hex:

nt!RtlpBreakWithStatusInstruction:
81881760 cc              int     3
1: kd> !process 0 0 notepad.exe
PROCESS 84b127f8  SessionId: 1  Cid: 0ff0    Peb: 7ffde000  ParentCid: 09a4
    DirBase: 6b25c280  ObjectTable: 9b80e530  HandleCount: 170.
    Image: notepad.exe

Here Cid is the process id. Next we will break inside the process context of notepad to set a local breakpoint. This can be acomplished fairly easily using the command !bpid 0ff0

1: kd> !bpid 0ff0
Finding wininit.exe (1)...
Finding winlogon.exe (1)...
Waiting for winlogon.exe to break.  This can take a couple of minutes...
Break instruction exception - code 80000003 (first chance)
Break into process ff0 set.  The next break should be in the desired process.
Break instruction exception - code 80000003 (first chance)
ntdll!DbgBreakPoint:
001b:77b82ea8 cc              int     3
0: kd> !process
PROCESS 84b127f8  SessionId: 1  Cid: 0ff0    Peb: 7ffde000  ParentCid: 09a4
    DirBase: 6b25c280  ObjectTable: 9b80e530  HandleCount: 170.
    Image: notepad.exe
    VadRoot 86164120 Vads 121 Clone 0 Private 1029. Modified 2564. Locked 0.
    DeviceMap 92071bf8
    Token                             9e30cca0
    ElapsedTime                       00:15:00.188
    UserTime                          00:00:00.093
    KernelTime                        00:00:00.124
    QuotaPoolUsage[PagedPool]         144744
    QuotaPoolUsage[NonPagedPool]      5808
    Working Set Sizes (now,min,max)  (3327, 50, 345) (13308KB, 200KB, 1380KB)
    PeakWorkingSetSize                3704
    VirtualSize                       77 Mb
    PeakVirtualSize                   106 Mb
    PageFaultCount                    5972
    MemoryPriority                    BACKGROUND
    BasePriority                      8
    CommitCharge                      1511

        THREAD 849ddd78  Cid 0ff0.0f58  Teb: 7ffdf000 Win32Thread: fe577e98 WAIT: (WrUserRequest) UserMode Non-Alertable
            84b01350  SynchronizationEvent

        THREAD 849dfa90  Cid 0ff0.0f88  Teb: 7ffdc000 Win32Thread: 00000000 WAIT: (WrQueue) UserMode Non-Alertable
            849e7cf0  QueueObject

        THREAD 84a41ac0  Cid 0ff0.083c  Teb: 7ffdb000 Win32Thread: 00000000 WAIT: (DelayExecution) UserMode Non-Alertable
            84a41b48  NotificationTimer

        THREAD 849957d0  Cid 0ff0.0b10  Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0

Now after confirming we're in the right process context, we can now proceed to set breakpoints.

Another way to do this is to use .process /i 84b127f8 to break into notepad's context and then set the breakpoints.