Search code examples
cassemblygccgdbx86-64

gdb commands gdbstub to write to _Unwind_DebugHook memory location


I ported a gdbstub for an OS I'm working on which runs on x86_64. The host which is running gdb is connected to the target that has the stub and the OS over serial. I have an int3 instruction in the source code to force the OS to jump into the stub's code which it does. The problem is if I try to step to the next instruction using nexti the stub stops responding and the host keeps timing out.

Looking at the packets that the host is sending I see this:

Sending packet: $Me1dc20,1:cc#6c...Ack
Timed out.
Timed out.
Timed out.
Ignoring packet error, continuing...

which means that the host is telling the stub to write cc (which is the opcode for int3) to memory location 0xe1dc20. I looked into that memory location and found this:

(gdb) x/16i 0xe1dc20

   0xe1dc20 <_Unwind_DebugHook>: retq   
   0xe1dc21:    data16 nopw %cs:0x0(%rax,%rax,1)
   0xe1dc2c:    nopl   0x0(%rax)

This function is part of gcc's code here https://github.com/gcc-mirror/gcc/blob/master/libgcc/unwind-dw2.c but it is not used anywhere in the source file that I am debugging.

Now obviously it is causing me troubles so I disabled memory writing functionality in my stub so that it longer responds to memory writing commands $M and $X and when I did I was able to execute nexti and step in gdb without issues. The stub uses the RFLAGS.TF for flow control.

The question is why is gdb trying to set a breakpoint in a function that I am not using anywhere and how do I prevent it from doing so? I thought about adding an if statement in the stub to ignore writes to this memory location but is there a less intrusive way of doing it?


Solution

  • The _Unwind_DebugHook symbol exists as a place for GDB (or any other debugger) to place a breakpoint and so catch exceptions. GDB will look for this symbol (in the debug info), and it it exists, place a breakpoint there.

    These breakpoints will always get inserted, even when doing something as simple as a stepi, just in case - you might be about to step to that address.

    One problem I see with the remote trace is that GDB will be expecting an OK packet to indicate that the write succeeded, this is why you're seeing the timeout messages.