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