#6751: gdb won't single step ----------------------------------------------+---------------------------- Reporter: grahamh | Owner: bonefish Type: bug | Status: assigned Priority: normal | Milestone: R1 Component: Applications/Command Line Tools | Version: Resolution: | R1/Development Blocked By: | Keywords: Platform: x86 | Has a Patch: 0 | Blocking: ----------------------------------------------+---------------------------- Comment (by grahamh): After some more investigation, here is what I think is happening. Asking for a single-step in gdb sends a message to the in-kernel debug facility, which sets the CPU's single-step flag in the context of the debugged thread. When the thread is resumed, it executes one instruction, then traps with an INT1 debug exception. The INT1 handler passes control to the generic trap handler, which calls gInterruptHandlerTable[1], which is x86_handle_debug_exception. So far, so good. The first that x86_handle_debug_exception() does is look at DR6 and DR7 to work out what kind of debug event this is. However, if the exception was from user space ( IFRAME_IS_USER(frame) ), it uses supposedly cached copies of the DRs from the thread's cpu info struct. The comment above that line says that they should have been saved by x86_exit_user_debug_at_kernel_entry - but as we have seen, that function isn't in the execution chain here. So the exception handler sees a bogus DR6=0, DR7=0, it can't understand the trap type, and it just returns. Future instructions are then all trapped in the same way, up until the process makes a system call (or possibly a context switch). At that point, x86_exit_user_debug_at_kernel_entry happens and DR6 and DR7 are stored in the thread struct. Single stepping is resumed when the system call ends and the thread's user mode context is restored. Now having correct DR values, the trap handler stops the process and returns to GDB after the next instruction - which is in the syscall trampoline in the commpage. Changing the top of x86_handle_debug_exception to always use DR6 and DR7 directly, rather than sometimes using thread->cpu->arch.dr6, fixes the problem with gdb single stepping. However, the behaviour looks like it was put in to fix a debugger crash, so it probably needs a more subtle fix. Just to finish, I noticed that this issue was also mentioned in bug #5742, and looks to have been introduced with changeset 36340, which was the fix for that one. -- Ticket URL: <http://dev.haiku-os.org/ticket/6751#comment:8> Haiku <http://dev.haiku-os.org> Haiku - the operating system.