NonInvasive debugging

Non-Invasive debugging is a useful technique to debug hung processes. The debugger suspends all threads in the process and has access to all threads, memory and register’s of the process.

To do non-invasive debugging via windbg/cdb check this link out:

To do this via WinDbg UI, press F6 or File->Attach to a Process…


While non-invasive debugging is in progress we also can have another instance of the debugger attached to the same process. This proves that for non-invasive debugging the debugger is not attached to the process reason being by default on Windows only one debugger can be attached at any time to a process. Also while debugging non-invasively common windbg commands like ‘g’ won’t work because we don’t have a debugger to the process  which can instruct the process to resume execution.

As written already: for non-invasive debugging the debugger suspends all the threads in the process so this also means that we can resume execution of these threads too. The command to do this is as follows…

0:000> ~*m

~m resumes a thread while ~n suspends a thread. If we don’t resume the threads we won’t see the process UI as the UI thread is also in a suspended state.

Now with two debuggers monitoring the process we can view the process’ memory via the non-invasive debugger as well. For e.g. when you set a breakpoint via the second debugger  (attached invasively) its interesting to see how the function code is modified by the debugger to get the breakpoint to work, see below e.g.

We’ve set a breakpoint on ntdll!ntopenfile. This is how the code looks when broken into by the debugger…

0:001> uf ntdll!ntopenfile
000007f9`25972f10 4c8bd1          mov     r10,rcx           <<<<—- This three byte instruction is replaced, see below
000007f9`25972f13 b831000000      mov     eax,31h
000007f9`25972f18 0f05            syscall
000007f9`25972f1a c3              ret

But during execution of the process (after setting breakpoint) and checking the assembler code via non-invasive debugger we see something different…

0:000> uf ntdll!ntopenfile
000007f9`25972f10 cc              int     3  <<<<——- Single byte instruction cc, and followed by
000007f9`25972f11 8bd1         mov     edx,ecx <<— 8bd1: remaining two bytes of the above three bytes instruction
000007f9`25972f13 b831000000      mov     eax,31h
000007f9`25972f18 0f05            syscall
000007f9`25972f1a c3              ret

In effect the original three byte instruction (4c8bd1) is replaced by (cc8bd1). The only change: 4c –> cc. cc evaluates to int 3. When the breakpoint is hit (or when we press Ctrl + Break) the breakpoint instruction is replaced by original op code i.e. 4c8bd1.

We could figure this out via the non-Invasive debugger. If a process is hung we can in effect go through the call stacks and find out potential hang scenarios, for e.g. a process waiting on a network drive.

Appreciate your comments...