Alexandre Julliard : ntdll: Always restore the context after an exception even if setting the debug registers fails .

Alexandre Julliard julliard at winehq.org
Fri Mar 5 09:42:54 CST 2010


Module: wine
Branch: master
Commit: c09df80620fe33f7f0de6eb7f19d20792f2c4774
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c09df80620fe33f7f0de6eb7f19d20792f2c4774

Author: Alexandre Julliard <julliard at 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;
 }
 




More information about the wine-cvs mailing list