ntdll: Better trap exception handling.

This commit is contained in:
Peter Beutner 2007-11-09 17:49:06 +01:00 committed by Alexandre Julliard
parent fc5316760b
commit db28edc790
2 changed files with 13 additions and 8 deletions

View File

@ -1040,16 +1040,21 @@ static void WINAPI raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context
{ {
if (rec->ExceptionCode == EXCEPTION_SINGLE_STEP) if (rec->ExceptionCode == EXCEPTION_SINGLE_STEP)
{ {
if (context->EFlags & 0x100) struct ntdll_thread_regs * const regs = ntdll_get_thread_regs();
{
context->EFlags &= ~0x100; /* clear single-step flag */ /* 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
else /* hardware breakpoint, fetch the debug registers */ * 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; context->ContextFlags = CONTEXT_DEBUG_REGISTERS;
NtGetContextThread(GetCurrentThread(), context); NtGetContextThread(GetCurrentThread(), context);
context->ContextFlags |= CONTEXT_FULL; /* restore flags */ context->ContextFlags |= CONTEXT_FULL; /* restore flags */
} }
context->EFlags &= ~0x100; /* clear single-step flag */
} }
__regs_RtlRaiseException( rec, context ); __regs_RtlRaiseException( rec, context );

View File

@ -489,7 +489,7 @@ static DWORD bpx_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *
/* single step exception on second nop */ /* single step exception on second nop */
ok( context->Eip == (DWORD)code_mem + 1, "eip is wrong: %x instead of %x\n", ok( context->Eip == (DWORD)code_mem + 1, "eip is wrong: %x instead of %x\n",
context->Eip, (DWORD)code_mem + 1); 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 /* 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"); */ ok( (context->Dr6 & 0xf) == 0, "B0...3 flags in Dr6 shouldn't be set\n"); */
context->EFlags |= 0x100; context->EFlags |= 0x100;
@ -497,7 +497,7 @@ static DWORD bpx_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *
/* hw bp exception on second nop */ /* hw bp exception on second nop */
ok( context->Eip == (DWORD)code_mem + 1, "eip is wrong: %x instead of %x\n", ok( context->Eip == (DWORD)code_mem + 1, "eip is wrong: %x instead of %x\n",
context->Eip, (DWORD)code_mem + 1); 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"); ok( !(context->Dr6 & 0x4000), "BS flag is set in Dr6\n");
context->Dr0 = 0; /* clear breakpoint */ context->Dr0 = 0; /* clear breakpoint */
context->EFlags |= 0x100; 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", ok( context->Eip == (DWORD)code_mem + 2, "eip is wrong: %x instead of %x\n",
context->Eip, (DWORD)code_mem + 2); context->Eip, (DWORD)code_mem + 2);
ok( (context->Dr6 & 0xf) == 0, "B0...3 flags in Dr6 shouldn't be set\n"); 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 */ context->Dr6 = 0; /* clear status register */