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

This commit is contained in:
Alexandre Julliard 2010-03-05 12:25:34 +01:00
parent b1c0441fac
commit c09df80620
1 changed files with 39 additions and 6 deletions

View File

@ -1187,6 +1187,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_context
* *
@ -1678,9 +1707,9 @@ static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context
break; break;
} }
status = NtRaiseException( rec, context, TRUE ); status = NtRaiseException( rec, context, TRUE );
if (status) raise_status( status, rec ); raise_status( status, rec );
done: 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 ); 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; NTSTATUS status;
status = NtRaiseException( rec, context, TRUE ); 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 ); NtRaiseException( rec, context, TRUE );
} }
done: 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 WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
{ {
NTSTATUS status = raise_exception( rec, context, 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; return status;
} }