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. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35951 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
9f018a4672
commit
feddedab0c
|
@ -250,6 +250,9 @@ typedef struct arch_cpu_info {
|
|||
|
||||
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;
|
||||
|
|
|
@ -806,6 +806,12 @@ x86_exit_user_debug_at_kernel_entry()
|
|||
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 @@ x86_exit_user_debug_at_kernel_entry()
|
|||
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 @@ x86_handle_debug_exception(struct iframe *frame)
|
|||
// 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
|
||||
|
|
Loading…
Reference in New Issue