ntdll: Better trap exception handling.
This commit is contained in:
parent
fc5316760b
commit
db28edc790
|
@ -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 );
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue