Peter Beutner : ntdll: Better trap exception handling.

Alexandre Julliard julliard at winehq.org
Tue Nov 13 08:34:39 CST 2007


Module: wine
Branch: master
Commit: db28edc790ccabdab20dfe31e3e06fe7e3e1e8b6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=db28edc790ccabdab20dfe31e3e06fe7e3e1e8b6

Author: Peter Beutner <p.beutner at gmx.net>
Date:   Fri Nov  9 17:49:06 2007 +0100

ntdll: Better trap exception handling.

---

 dlls/ntdll/signal_i386.c     |   15 ++++++++++-----
 dlls/ntdll/tests/exception.c |    6 +++---
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index 793b22e..df62a30 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -1040,16 +1040,21 @@ static void WINAPI raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context
 {
     if (rec->ExceptionCode == EXCEPTION_SINGLE_STEP)
     {
-        if (context->EFlags & 0x100)
-        {
-            context->EFlags &= ~0x100;  /* clear single-step flag */
-        }
-        else  /* hardware breakpoint, fetch the debug registers */
+        struct ntdll_thread_regs * const regs = ntdll_get_thread_regs();
+
+        /* when single stepping can't tell whether this is a hw bp or a
+         * single step interrupt. try to avoid as much overhead as possible
+         * and only do a server call if there is any hw bp enabled. */
+
+        if( !(context->EFlags & 0x100) || (regs->dr7 & 0xff) )
         {
+            /* (possible) hardware breakpoint, fetch the debug registers */
             context->ContextFlags = CONTEXT_DEBUG_REGISTERS;
             NtGetContextThread(GetCurrentThread(), context);
             context->ContextFlags |= CONTEXT_FULL;  /* restore flags */
         }
+
+        context->EFlags &= ~0x100;  /* clear single-step flag */
     }
 
     __regs_RtlRaiseException( rec, context );
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index ce5d31b..9bd5678 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -489,7 +489,7 @@ static DWORD bpx_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *
         /* single step exception on second nop */
         ok( context->Eip == (DWORD)code_mem + 1, "eip is wrong: %x instead of %x\n",
                                                  context->Eip, (DWORD)code_mem + 1);
-        todo_wine{ ok( (context->Dr6 & 0x4000), "BS flag is not set in Dr6\n"); };
+        ok( (context->Dr6 & 0x4000), "BS flag is not set in Dr6\n");
        /* depending on the win version the B0 bit is already set here as well
         ok( (context->Dr6 & 0xf) == 0, "B0...3 flags in Dr6 shouldn't be set\n"); */
         context->EFlags |= 0x100;
@@ -497,7 +497,7 @@ static DWORD bpx_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *
         /* hw bp exception on second nop */
         ok( context->Eip == (DWORD)code_mem + 1, "eip is wrong: %x instead of %x\n",
                                                  context->Eip, (DWORD)code_mem + 1);
-        todo_wine{ ok( (context->Dr6 & 0xf) == 1, "B0 flag is not set in Dr6\n"); };
+        ok( (context->Dr6 & 0xf) == 1, "B0 flag is not set in Dr6\n");
         ok( !(context->Dr6 & 0x4000), "BS flag is set in Dr6\n");
         context->Dr0 = 0;       /* clear breakpoint */
         context->EFlags |= 0x100;
@@ -506,7 +506,7 @@ static DWORD bpx_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *
         ok( context->Eip == (DWORD)code_mem + 2, "eip is wrong: %x instead of %x\n",
                                                  context->Eip, (DWORD)code_mem + 2);
         ok( (context->Dr6 & 0xf) == 0, "B0...3 flags in Dr6 shouldn't be set\n");
-        todo_wine{ ok( (context->Dr6 & 0x4000), "BS flag is not set in Dr6\n"); };
+        ok( (context->Dr6 & 0x4000), "BS flag is not set in Dr6\n");
     }
 
     context->Dr6 = 0;  /* clear status register */




More information about the wine-cvs mailing list