Handle kernel debug exceptions similar to those in userland. This allows to

continue kernel breakpoints -- we would just retrigger the breakpoint when
continuing before.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30210 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-04-16 22:18:02 +00:00
parent 31d9352ff6
commit 8753babd62
@@ -788,12 +788,6 @@ x86_handle_debug_exception(struct iframe *frame)
TRACE(("i386_handle_debug_exception(): DR6: %lx, DR7: %lx\n", dr6, dr7)); TRACE(("i386_handle_debug_exception(): DR6: %lx, DR7: %lx\n", dr6, dr7));
if (!IFRAME_IS_USER(frame)) {
panic("debug exception in kernel mode: dr6: 0x%lx, dr7: 0x%lx", dr6,
dr7);
return;
}
// check, which exception condition applies // check, which exception condition applies
if (dr6 & X86_DR6_BREAKPOINT_MASK) { if (dr6 & X86_DR6_BREAKPOINT_MASK) {
// breakpoint // breakpoint
@@ -814,40 +808,59 @@ x86_handle_debug_exception(struct iframe *frame)
} }
} }
// enable interrupts and notify the debugger if (IFRAME_IS_USER(frame)) {
enable_interrupts(); // enable interrupts and notify the debugger
enable_interrupts();
if (watchpoint) if (watchpoint)
user_debug_watchpoint_hit(); user_debug_watchpoint_hit();
else else
user_debug_breakpoint_hit(false); user_debug_breakpoint_hit(false);
} else {
panic("hit kernel %spoint: dr6: 0x%lx, dr7: 0x%lx",
watchpoint ? "watch" : "break", dr6, dr7);
}
} else if (dr6 & (1 << X86_DR6_BD)) { } else if (dr6 & (1 << X86_DR6_BD)) {
// general detect exception // general detect exception
// Occurs only, if GD in DR7 is set (which we don't do) and someone // Occurs only, if GD in DR7 is set (which we don't do) and someone
// tries to write to the debug registers. // tries to write to the debug registers.
dprintf("i386_handle_debug_exception(): ignoring spurious general " if (IFRAME_IS_USER(frame)) {
"detect exception\n"); dprintf("i386_handle_debug_exception(): ignoring spurious general "
"detect exception\n");
enable_interrupts(); enable_interrupts();
} else
panic("spurious general detect exception in kernel mode");
} else if ((dr6 & (1 << X86_DR6_BS)) || sQEmuSingleStepHack) { } else if ((dr6 & (1 << X86_DR6_BS)) || sQEmuSingleStepHack) {
// single step // single step
// enable interrupts and notify the debugger if (IFRAME_IS_USER(frame)) {
enable_interrupts(); // enable interrupts and notify the debugger
enable_interrupts();
user_debug_single_stepped(); user_debug_single_stepped();
} else
panic("kernel single step");
} else if (dr6 & (1 << X86_DR6_BT)) { } else if (dr6 & (1 << X86_DR6_BT)) {
// task switch // task switch
// Occurs only, if T in EFLAGS is set (which we don't do). // Occurs only, if T in EFLAGS is set (which we don't do).
dprintf("i386_handle_debug_exception(): ignoring spurious task switch " if (IFRAME_IS_USER(frame)) {
"exception\n"); dprintf("i386_handle_debug_exception(): ignoring spurious task switch "
"exception\n");
enable_interrupts(); enable_interrupts();
} else
panic("spurious task switch exception in kernel mode");
} else { } else {
TRACE(("i386_handle_debug_exception(): ignoring spurious debug " if (IFRAME_IS_USER(frame)) {
"exception (no condition recognized)\n")); TRACE(("i386_handle_debug_exception(): ignoring spurious debug "
"exception (no condition recognized)\n"));
enable_interrupts(); enable_interrupts();
} else {
panic("spurious debug exception in kernel mode (no condition "
"recognized)");
}
} }
} }