Alexandre Julliard : ntdll: Always restore the context after an exception even if setting the debug registers fails .
Module: wine Branch: master Commit: c09df80620fe33f7f0de6eb7f19d20792f2c4774 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c09df80620fe33f7f0de6eb7f1... Author: Alexandre Julliard <julliard(a)winehq.org> Date: Fri Mar 5 12:25:34 2010 +0100 ntdll: Always restore the context after an exception even if setting the debug registers fails. --- dlls/ntdll/signal_i386.c | 45 +++++++++++++++++++++++++++++++++++++++------ 1 files changed, 39 insertions(+), 6 deletions(-) diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 4eccb61..4998820 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -1188,6 +1188,35 @@ void set_cpu_context( const CONTEXT *context ) /*********************************************************************** + * set_debug_registers + */ +static void set_debug_registers( const CONTEXT *context ) +{ + DWORD flags = context->ContextFlags & ~CONTEXT_i386; + context_t server_context; + + if (!(flags & CONTEXT_DEBUG_REGISTERS)) return; + if (ntdll_get_thread_data()->dr0 == context->Dr0 && + ntdll_get_thread_data()->dr1 == context->Dr1 && + ntdll_get_thread_data()->dr2 == context->Dr2 && + ntdll_get_thread_data()->dr3 == context->Dr3 && + ntdll_get_thread_data()->dr6 == context->Dr6 && + ntdll_get_thread_data()->dr7 == context->Dr7) return; + + context_to_server( &server_context, context ); + + SERVER_START_REQ( set_thread_context ) + { + req->handle = wine_server_obj_handle( GetCurrentThread() ); + req->suspend = 0; + wine_server_add_data( req, &server_context, sizeof(server_context) ); + wine_server_call( req ); + } + SERVER_END_REQ; +} + + +/*********************************************************************** * copy_context * * Copy a register context according to the flags. @@ -1678,9 +1707,9 @@ static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context break; } status = NtRaiseException( rec, context, TRUE ); - if (status) raise_status( status, rec ); + raise_status( status, rec ); done: - NtSetContextThread( GetCurrentThread(), context ); + set_cpu_context( context ); } @@ -1709,7 +1738,7 @@ static void WINAPI raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context } status = NtRaiseException( rec, context, TRUE ); - if (status) raise_status( status, rec ); + raise_status( status, rec ); } @@ -1723,7 +1752,7 @@ static void WINAPI raise_generic_exception( EXCEPTION_RECORD *rec, CONTEXT *cont NTSTATUS status; status = NtRaiseException( rec, context, TRUE ); - if (status) raise_status( status, rec ); + raise_status( status, rec ); } @@ -1755,7 +1784,7 @@ static void WINAPI raise_vm86_sti_exception( EXCEPTION_RECORD *rec, CONTEXT *con NtRaiseException( rec, context, TRUE ); } done: - NtSetContextThread( GetCurrentThread(), context ); + set_cpu_context( context ); } @@ -2345,7 +2374,11 @@ DEFINE_REGS_ENTRYPOINT( RtlUnwind, 4 ) NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance ) { NTSTATUS status = raise_exception( rec, context, first_chance ); - if (status == STATUS_SUCCESS) NtSetContextThread( GetCurrentThread(), context ); + if (status == STATUS_SUCCESS) + { + set_debug_registers( context ); + set_cpu_context( context ); + } return status; }
participants (1)
-
Alexandre Julliard