Module: wine Branch: master Commit: 5e2b0585cd4f39fdc916d4afcd19f2d1fa4fd21c URL: https://source.winehq.org/git/wine.git/?a=commit;h=5e2b0585cd4f39fdc916d4afc...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Sep 12 19:27:05 2019 +0200
ntdll: Handle single step exception in signal handler on i386.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/signal_i386.c | 44 +++++++++++++------------------------------- 1 file changed, 13 insertions(+), 31 deletions(-)
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 5699a99932..580bfb2d5c 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -1988,36 +1988,6 @@ done: }
-/********************************************************************** - * raise_trap_exception - */ -static void WINAPI raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context ) -{ - NTSTATUS status; - - if (rec->ExceptionCode == EXCEPTION_SINGLE_STEP) - { - /* 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) || (x86_thread_data()->dr7 & 0xff) ) - { - /* (possible) hardware breakpoint, fetch the debug registers */ - DWORD saved_flags = context->ContextFlags; - context->ContextFlags = CONTEXT_DEBUG_REGISTERS; - NtGetContextThread(GetCurrentThread(), context); - context->ContextFlags |= saved_flags; /* restore flags */ - } - - context->EFlags &= ~0x100; /* clear single-step flag */ - } - - status = NtRaiseException( rec, context, TRUE ); - raise_status( status, rec ); -} - - /********************************************************************** * raise_generic_exception * @@ -2141,6 +2111,18 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext ) { case TRAP_x86_TRCTRAP: /* Single-step exception */ stack->rec.ExceptionCode = EXCEPTION_SINGLE_STEP; + /* 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 (!(stack->context.EFlags & 0x100) || (stack->context.Dr7 & 0xff)) + { + /* (possible) hardware breakpoint, fetch the debug registers */ + DWORD saved_flags = stack->context.ContextFlags; + stack->context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + NtGetContextThread( GetCurrentThread(), &stack->context ); + stack->context.ContextFlags |= saved_flags; /* restore flags */ + } + stack->context.EFlags &= ~0x100; /* clear single-step flag */ break; case TRAP_x86_BPTFLT: /* Breakpoint exception */ stack->rec.ExceptionAddress = (char *)stack->rec.ExceptionAddress - 1; /* back up over the int3 instruction */ @@ -2153,7 +2135,7 @@ static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext ) stack->rec.ExceptionInformation[2] = 0; /* FIXME */ break; } - setup_raise_exception( context, stack, raise_trap_exception ); + setup_raise_exception( context, stack, raise_generic_exception ); }