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
*
@ -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;
}