[haiku-commits] r35951 - in haiku/trunk: headers/private/kernel/arch/x86 src/system/kernel/arch/x86
- From: ingo_weinhold@xxxxxx
- To: haiku-commits@xxxxxxxxxxxxx
- Date: Fri, 26 Mar 2010 01:03:54 +0100 (CET)
Author: bonefish
Date: 2010-03-26 01:03:53 +0100 (Fri, 26 Mar 2010)
New Revision: 35951
Changeset: http://dev.haiku-os.org/changeset/35951/haiku
Modified:
haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h
haiku/trunk/src/system/kernel/arch/x86/arch_user_debugger.cpp
Log:
x86:
Added fields for temporary storage of the debug registers dr6 and dr7 to the
arch_cpu_info structure. The actual registers are stored at the beginning of
x86_exit_user_debug_at_kernel_entry() and read in
x86_handle_debug_exception().
The problem was that x86_exit_user_debug_at_kernel_entry() itself overwrote
dr7 and, if kernel breakpoints were enabled, dr6 could be overwritten anytime
after. So x86_handle_debug_exception() would find incorrect values in the
registers (definitely in dr7) and thus interpret the detected debug condition
incorrectly. Usually watchpoints were recognized as breakpoints.
Modified: haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h
===================================================================
--- haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h 2010-03-25
21:08:05 UTC (rev 35950)
+++ haiku/trunk/headers/private/kernel/arch/x86/arch_cpu.h 2010-03-26
00:03:53 UTC (rev 35951)
@@ -250,6 +250,9 @@
struct vm_translation_map_arch_info* active_translation_map;
+ uint32 dr6; // temporary storage for debug
registers (cf.
+ uint32 dr7; //
x86_exit_user_debug_at_kernel_entry())
+
// local TSS for this cpu
struct tss tss;
struct tss double_fault_tss;
Modified: haiku/trunk/src/system/kernel/arch/x86/arch_user_debugger.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_user_debugger.cpp
2010-03-25 21:08:05 UTC (rev 35950)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_user_debugger.cpp
2010-03-26 00:03:53 UTC (rev 35951)
@@ -806,6 +806,12 @@
if (!(thread->flags & THREAD_FLAGS_BREAKPOINTS_INSTALLED))
return;
+ // We need to save the current values of dr6 and dr7 in the CPU
structure,
+ // since in case of a debug exception we might overwrite them before
+ // x86_handle_debug_exception() is called.
+ asm("movl %%dr6, %0" : "=r"(thread->cpu->arch.dr6));
+ asm("movl %%dr7, %0" : "=r"(thread->cpu->arch.dr7));
+
GRAB_THREAD_LOCK();
// disable user breakpoints
@@ -829,10 +835,11 @@
void
x86_handle_debug_exception(struct iframe *frame)
{
- // get debug status and control registers
- uint32 dr6, dr7;
- asm("movl %%dr6, %0" : "=r"(dr6));
- asm("movl %%dr7, %0" : "=r"(dr7));
+ // get debug status and control registers (saved earlier in
+ // x86_exit_user_debug_at_kernel_entry())
+ struct thread* thread = thread_get_current_thread();
+ uint32 dr6 = thread->cpu->arch.dr6;
+ uint32 dr7 = thread->cpu->arch.dr7;
TRACE(("i386_handle_debug_exception(): DR6: %lx, DR7: %lx\n", dr6,
dr7));
@@ -889,7 +896,6 @@
// Determine whether the exception occurred at a
syscall/trap
// kernel entry or whether this is genuine kernel
single-stepping.
bool inKernel = true;
- struct thread* thread = thread_get_current_thread();
if (thread->team != team_get_kernel_team()
&& i386_get_user_iframe() == NULL) {
// TODO: This is not yet fully correct, since a
newly created
Other related posts:
- » [haiku-commits] r35951 - in haiku/trunk: headers/private/kernel/arch/x86 src/system/kernel/arch/x86 - ingo_weinhold