ntdll: Share exception dispatch implementation across platforms.
This commit is contained in:
parent
61564202b5
commit
8bd411da0a
6 changed files with 88 additions and 254 deletions
|
@ -36,6 +36,7 @@
|
|||
#include "ntdll_misc.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(threadname);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -58,7 +59,7 @@ static RTL_CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0
|
|||
|
||||
static PRTL_EXCEPTION_FILTER unhandled_exception_filter;
|
||||
|
||||
const char *debugstr_exception_code( DWORD code )
|
||||
static const char *debugstr_exception_code( DWORD code )
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
|
@ -143,7 +144,7 @@ static ULONG remove_vectored_handler( struct list *handler_list, VECTORED_HANDLE
|
|||
*
|
||||
* Call the vectored handlers chain.
|
||||
*/
|
||||
LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
static LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
{
|
||||
struct list *ptr;
|
||||
LONG ret = EXCEPTION_CONTINUE_SEARCH;
|
||||
|
@ -185,6 +186,77 @@ LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
|
|||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* dispatch_exception
|
||||
*/
|
||||
NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
{
|
||||
NTSTATUS status;
|
||||
DWORD i;
|
||||
|
||||
switch (rec->ExceptionCode)
|
||||
{
|
||||
case EXCEPTION_WINE_STUB:
|
||||
if (rec->ExceptionInformation[1] >> 16)
|
||||
MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n",
|
||||
rec->ExceptionAddress,
|
||||
(char *)rec->ExceptionInformation[0], (char *)rec->ExceptionInformation[1] );
|
||||
else
|
||||
MESSAGE( "wine: Call from %p to unimplemented function %s.%u, aborting\n",
|
||||
rec->ExceptionAddress,
|
||||
(char *)rec->ExceptionInformation[0], (USHORT)rec->ExceptionInformation[1] );
|
||||
break;
|
||||
|
||||
case EXCEPTION_WINE_NAME_THREAD:
|
||||
if (rec->ExceptionInformation[0] == 0x1000)
|
||||
{
|
||||
const char *name = (char *)rec->ExceptionInformation[1];
|
||||
DWORD tid = (DWORD)rec->ExceptionInformation[2];
|
||||
|
||||
if (tid == -1 || tid == GetCurrentThreadId())
|
||||
WARN_(threadname)( "Thread renamed to %s\n", debugstr_a(name) );
|
||||
else
|
||||
WARN_(threadname)( "Thread ID %04lx renamed to %s\n", tid, debugstr_a(name) );
|
||||
set_native_thread_name( tid, name );
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_PRINTEXCEPTION_C:
|
||||
WARN( "%s\n", debugstr_an((char *)rec->ExceptionInformation[1], rec->ExceptionInformation[0] - 1) );
|
||||
break;
|
||||
|
||||
case DBG_PRINTEXCEPTION_WIDE_C:
|
||||
WARN( "%s\n", debugstr_wn((WCHAR *)rec->ExceptionInformation[1], rec->ExceptionInformation[0] - 1) );
|
||||
break;
|
||||
|
||||
case STATUS_ASSERTION_FAILURE:
|
||||
ERR( "assertion failure exception\n" );
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!TRACE_ON(seh)) WARN( "%s exception (code=%lx) raised\n",
|
||||
debugstr_exception_code(rec->ExceptionCode), rec->ExceptionCode );
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE( "code=%lx (%s) flags=%lx addr=%p\n",
|
||||
rec->ExceptionCode, debugstr_exception_code(rec->ExceptionCode),
|
||||
rec->ExceptionFlags, rec->ExceptionAddress );
|
||||
for (i = 0; i < min( EXCEPTION_MAXIMUM_PARAMETERS, rec->NumberParameters ); i++)
|
||||
TRACE( " info[%ld]=%p\n", i, (void *)rec->ExceptionInformation[i] );
|
||||
TRACE_CONTEXT( context );
|
||||
|
||||
if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION)
|
||||
NtContinue( context, FALSE );
|
||||
|
||||
if ((status = call_seh_handlers( rec, context )) == STATUS_SUCCESS)
|
||||
NtContinue( context, FALSE );
|
||||
|
||||
if (status != STATUS_UNHANDLED_EXCEPTION) RtlRaiseStatus( status );
|
||||
return NtRaiseException( rec, context, FALSE );
|
||||
}
|
||||
|
||||
|
||||
#if defined(__WINE_PE_BUILD) && !defined(__i386__)
|
||||
|
||||
/*******************************************************************
|
||||
|
|
|
@ -60,7 +60,8 @@ extern UINT_PTR page_size;
|
|||
#endif
|
||||
|
||||
/* exceptions */
|
||||
extern LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context );
|
||||
extern NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *context );
|
||||
extern NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context );
|
||||
extern NTSTATUS WINAPI dispatch_user_callback( void *args, ULONG len, ULONG id );
|
||||
extern EXCEPTION_DISPOSITION WINAPI user_callback_handler( EXCEPTION_RECORD *record, void *frame,
|
||||
CONTEXT *context, void *dispatch );
|
||||
|
@ -86,7 +87,6 @@ extern void (WINAPI *pWow64PrepareForException)( EXCEPTION_RECORD *rec, CONTEXT
|
|||
|
||||
/* debug helpers */
|
||||
extern LPCSTR debugstr_us( const UNICODE_STRING *str );
|
||||
extern const char *debugstr_exception_code( DWORD code );
|
||||
extern void set_native_thread_name( DWORD tid, const char *name );
|
||||
|
||||
/* init routines */
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(threadname);
|
||||
|
||||
|
||||
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
|
||||
|
@ -335,11 +334,11 @@ static DWORD call_teb_handler( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCH
|
|||
|
||||
|
||||
/**********************************************************************
|
||||
* call_function_handlers
|
||||
* call_seh_handlers
|
||||
*
|
||||
* Call the per-function handlers.
|
||||
* Call the SEH handlers.
|
||||
*/
|
||||
static NTSTATUS call_function_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
||||
NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
||||
{
|
||||
EXCEPTION_REGISTRATION_RECORD *teb_frame = NtCurrentTeb()->Tib.ExceptionList;
|
||||
UNWIND_HISTORY_TABLE table;
|
||||
|
@ -441,64 +440,6 @@ static NTSTATUS call_function_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_con
|
|||
/*******************************************************************
|
||||
* KiUserExceptionDispatcher (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
{
|
||||
NTSTATUS status;
|
||||
DWORD c;
|
||||
|
||||
if (rec->ExceptionCode == EXCEPTION_WINE_STUB)
|
||||
{
|
||||
if (rec->ExceptionInformation[1] >> 16)
|
||||
MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n",
|
||||
rec->ExceptionAddress,
|
||||
(char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] );
|
||||
else
|
||||
MESSAGE( "wine: Call from %p to unimplemented function %s.%Id, aborting\n",
|
||||
rec->ExceptionAddress,
|
||||
(char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] );
|
||||
}
|
||||
else if (rec->ExceptionCode == EXCEPTION_WINE_NAME_THREAD && rec->ExceptionInformation[0] == 0x1000)
|
||||
{
|
||||
if ((DWORD)rec->ExceptionInformation[2] == -1 || (DWORD)rec->ExceptionInformation[2] == GetCurrentThreadId())
|
||||
WARN_(threadname)( "Thread renamed to %s\n", debugstr_a((char *)rec->ExceptionInformation[1]) );
|
||||
else
|
||||
WARN_(threadname)( "Thread ID %04lx renamed to %s\n", (DWORD)rec->ExceptionInformation[2],
|
||||
debugstr_a((char *)rec->ExceptionInformation[1]) );
|
||||
|
||||
set_native_thread_name((DWORD)rec->ExceptionInformation[2], (char *)rec->ExceptionInformation[1]);
|
||||
}
|
||||
else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_C)
|
||||
{
|
||||
WARN( "%s\n", debugstr_an((char *)rec->ExceptionInformation[1], rec->ExceptionInformation[0] - 1) );
|
||||
}
|
||||
else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_WIDE_C)
|
||||
{
|
||||
WARN( "%s\n", debugstr_wn((WCHAR *)rec->ExceptionInformation[1], rec->ExceptionInformation[0] - 1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rec->ExceptionCode == STATUS_ASSERTION_FAILURE)
|
||||
ERR( "%s exception (code=%lx) raised\n", debugstr_exception_code(rec->ExceptionCode), rec->ExceptionCode );
|
||||
else
|
||||
WARN( "%s exception (code=%lx) raised\n", debugstr_exception_code(rec->ExceptionCode), rec->ExceptionCode );
|
||||
|
||||
}
|
||||
|
||||
TRACE( "code=%lx flags=%lx addr=%p\n",
|
||||
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
|
||||
for (c = 0; c < rec->NumberParameters; c++)
|
||||
TRACE( " info[%ld]=%08Ix\n", c, rec->ExceptionInformation[c] );
|
||||
TRACE_CONTEXT( context );
|
||||
|
||||
if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION)
|
||||
NtContinue( context, FALSE );
|
||||
|
||||
if ((status = call_function_handlers( rec, context )) == STATUS_SUCCESS)
|
||||
NtContinue( context, FALSE );
|
||||
|
||||
if (status != STATUS_UNHANDLED_EXCEPTION) RtlRaiseStatus( status );
|
||||
return NtRaiseException( rec, context, FALSE );
|
||||
}
|
||||
__ASM_GLOBAL_FUNC( KiUserExceptionDispatcher,
|
||||
__ASM_SEH(".seh_custom 0xee,0x02\n\t") /* MSFT_OP_CONTEXT */
|
||||
__ASM_SEH(".seh_endprologue\n\t")
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(threadname);
|
||||
|
||||
|
||||
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
|
||||
|
@ -338,11 +337,11 @@ static DWORD call_teb_handler( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCH
|
|||
|
||||
|
||||
/**********************************************************************
|
||||
* call_function_handlers
|
||||
* call_seh_handlers
|
||||
*
|
||||
* Call the per-function handlers.
|
||||
* Call the SEH handlers.
|
||||
*/
|
||||
static NTSTATUS call_function_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
||||
NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
||||
{
|
||||
EXCEPTION_REGISTRATION_RECORD *teb_frame = NtCurrentTeb()->Tib.ExceptionList;
|
||||
UNWIND_HISTORY_TABLE table;
|
||||
|
@ -441,65 +440,6 @@ static NTSTATUS call_function_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_con
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
{
|
||||
NTSTATUS status;
|
||||
DWORD c;
|
||||
|
||||
if (rec->ExceptionCode == EXCEPTION_WINE_STUB)
|
||||
{
|
||||
if (rec->ExceptionInformation[1] >> 16)
|
||||
MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n",
|
||||
rec->ExceptionAddress,
|
||||
(char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] );
|
||||
else
|
||||
MESSAGE( "wine: Call from %p to unimplemented function %s.%Id, aborting\n",
|
||||
rec->ExceptionAddress,
|
||||
(char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] );
|
||||
}
|
||||
else if (rec->ExceptionCode == EXCEPTION_WINE_NAME_THREAD && rec->ExceptionInformation[0] == 0x1000)
|
||||
{
|
||||
if ((DWORD)rec->ExceptionInformation[2] == -1 || (DWORD)rec->ExceptionInformation[2] == GetCurrentThreadId())
|
||||
WARN_(threadname)( "Thread renamed to %s\n", debugstr_a((char *)rec->ExceptionInformation[1]) );
|
||||
else
|
||||
WARN_(threadname)( "Thread ID %04lx renamed to %s\n", (DWORD)rec->ExceptionInformation[2],
|
||||
debugstr_a((char *)rec->ExceptionInformation[1]) );
|
||||
|
||||
set_native_thread_name((DWORD)rec->ExceptionInformation[2], (char *)rec->ExceptionInformation[1]);
|
||||
}
|
||||
else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_C)
|
||||
{
|
||||
WARN( "%s\n", debugstr_an((char *)rec->ExceptionInformation[1], rec->ExceptionInformation[0] - 1) );
|
||||
}
|
||||
else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_WIDE_C)
|
||||
{
|
||||
WARN( "%s\n", debugstr_wn((WCHAR *)rec->ExceptionInformation[1], rec->ExceptionInformation[0] - 1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rec->ExceptionCode == STATUS_ASSERTION_FAILURE)
|
||||
ERR( "%s exception (code=%lx) raised\n", debugstr_exception_code(rec->ExceptionCode), rec->ExceptionCode );
|
||||
else
|
||||
WARN( "%s exception (code=%lx) raised\n", debugstr_exception_code(rec->ExceptionCode), rec->ExceptionCode );
|
||||
}
|
||||
|
||||
TRACE( "code=%lx flags=%lx addr=%p\n",
|
||||
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
|
||||
for (c = 0; c < rec->NumberParameters; c++)
|
||||
TRACE( " info[%ld]=%016I64x\n", c, rec->ExceptionInformation[c] );
|
||||
TRACE_CONTEXT( context );
|
||||
|
||||
if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION)
|
||||
NtContinue( context, FALSE );
|
||||
|
||||
if ((status = call_function_handlers( rec, context )) == STATUS_SUCCESS)
|
||||
NtContinue( context, FALSE );
|
||||
|
||||
if (status != STATUS_UNHANDLED_EXCEPTION) RtlRaiseStatus( status );
|
||||
return NtRaiseException( rec, context, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* KiUserExceptionDispatcher (NTDLL.@)
|
||||
*/
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(threadname);
|
||||
|
||||
struct x86_thread_data
|
||||
{
|
||||
|
@ -139,11 +138,11 @@ static DWORD unwind_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECOR
|
|||
|
||||
|
||||
/**********************************************************************
|
||||
* call_stack_handlers
|
||||
* call_seh_handlers
|
||||
*
|
||||
* Call the stack handlers chain.
|
||||
* Call the SEH handlers chain.
|
||||
*/
|
||||
static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
{
|
||||
EXCEPTION_REGISTRATION_RECORD *frame, *dispatch, *nested_frame;
|
||||
DWORD res;
|
||||
|
@ -195,64 +194,6 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
|
|||
/*******************************************************************
|
||||
* KiUserExceptionDispatcher (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
{
|
||||
NTSTATUS status;
|
||||
DWORD c;
|
||||
|
||||
if (rec->ExceptionCode == EXCEPTION_WINE_STUB)
|
||||
{
|
||||
if (rec->ExceptionInformation[1] >> 16)
|
||||
MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n",
|
||||
rec->ExceptionAddress,
|
||||
(char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] );
|
||||
else
|
||||
MESSAGE( "wine: Call from %p to unimplemented function %s.%Id, aborting\n",
|
||||
rec->ExceptionAddress,
|
||||
(char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] );
|
||||
}
|
||||
else if (rec->ExceptionCode == EXCEPTION_WINE_NAME_THREAD && rec->ExceptionInformation[0] == 0x1000)
|
||||
{
|
||||
if ((DWORD)rec->ExceptionInformation[2] == -1 || (DWORD)rec->ExceptionInformation[2] == GetCurrentThreadId())
|
||||
WARN_(threadname)( "Thread renamed to %s\n", debugstr_a((char *)rec->ExceptionInformation[1]) );
|
||||
else
|
||||
WARN_(threadname)( "Thread ID %04lx renamed to %s\n", (DWORD)rec->ExceptionInformation[2],
|
||||
debugstr_a((char *)rec->ExceptionInformation[1]) );
|
||||
|
||||
set_native_thread_name((DWORD)rec->ExceptionInformation[2], (char *)rec->ExceptionInformation[1]);
|
||||
}
|
||||
else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_C)
|
||||
{
|
||||
WARN( "%s\n", debugstr_an((char *)rec->ExceptionInformation[1], rec->ExceptionInformation[0] - 1) );
|
||||
}
|
||||
else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_WIDE_C)
|
||||
{
|
||||
WARN( "%s\n", debugstr_wn((WCHAR *)rec->ExceptionInformation[1], rec->ExceptionInformation[0] - 1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rec->ExceptionCode == STATUS_ASSERTION_FAILURE)
|
||||
ERR( "%s exception (code=%lx) raised\n", debugstr_exception_code(rec->ExceptionCode), rec->ExceptionCode );
|
||||
else
|
||||
WARN( "%s exception (code=%lx) raised\n", debugstr_exception_code(rec->ExceptionCode), rec->ExceptionCode );
|
||||
}
|
||||
|
||||
TRACE( "code=%lx flags=%lx addr=%p\n",
|
||||
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
|
||||
for (c = 0; c < rec->NumberParameters; c++)
|
||||
TRACE( " info[%ld]=%08Ix\n", c, rec->ExceptionInformation[c] );
|
||||
TRACE_CONTEXT( context );
|
||||
|
||||
if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION)
|
||||
NtContinue( context, FALSE );
|
||||
|
||||
if ((status = call_stack_handlers( rec, context )) == STATUS_SUCCESS)
|
||||
NtContinue( context, FALSE );
|
||||
|
||||
if (status != STATUS_UNHANDLED_EXCEPTION) RtlRaiseStatus( status );
|
||||
return NtRaiseException( rec, context, FALSE );
|
||||
}
|
||||
|
||||
__ASM_STDCALL_FUNC( KiUserExceptionDispatcher, 8,
|
||||
"pushl 4(%esp)\n\t"
|
||||
"pushl 4(%esp)\n\t"
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(threadname);
|
||||
|
||||
|
||||
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
|
||||
|
@ -258,11 +257,11 @@ static DWORD call_teb_handler( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCH
|
|||
|
||||
|
||||
/**********************************************************************
|
||||
* call_stack_handlers
|
||||
* call_seh_handlers
|
||||
*
|
||||
* Call the stack handlers chain.
|
||||
* Call the SEH handlers chain.
|
||||
*/
|
||||
static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
||||
NTSTATUS call_seh_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_context )
|
||||
{
|
||||
EXCEPTION_REGISTRATION_RECORD *teb_frame = NtCurrentTeb()->Tib.ExceptionList;
|
||||
UNWIND_HISTORY_TABLE table;
|
||||
|
@ -359,65 +358,6 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
|
|||
}
|
||||
|
||||
|
||||
NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||
{
|
||||
NTSTATUS status;
|
||||
DWORD c;
|
||||
|
||||
if (rec->ExceptionCode == EXCEPTION_WINE_STUB)
|
||||
{
|
||||
if (rec->ExceptionInformation[1] >> 16)
|
||||
MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n",
|
||||
rec->ExceptionAddress,
|
||||
(char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] );
|
||||
else
|
||||
MESSAGE( "wine: Call from %p to unimplemented function %s.%I64d, aborting\n",
|
||||
rec->ExceptionAddress,
|
||||
(char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] );
|
||||
}
|
||||
else if (rec->ExceptionCode == EXCEPTION_WINE_NAME_THREAD && rec->ExceptionInformation[0] == 0x1000)
|
||||
{
|
||||
if ((DWORD)rec->ExceptionInformation[2] == -1 || (DWORD)rec->ExceptionInformation[2] == GetCurrentThreadId())
|
||||
WARN_(threadname)( "Thread renamed to %s\n", debugstr_a((char *)rec->ExceptionInformation[1]) );
|
||||
else
|
||||
WARN_(threadname)( "Thread ID %04lx renamed to %s\n", (DWORD)rec->ExceptionInformation[2],
|
||||
debugstr_a((char *)rec->ExceptionInformation[1]) );
|
||||
|
||||
set_native_thread_name((DWORD)rec->ExceptionInformation[2], (char *)rec->ExceptionInformation[1]);
|
||||
}
|
||||
else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_C)
|
||||
{
|
||||
WARN( "%s\n", debugstr_an((char *)rec->ExceptionInformation[1], rec->ExceptionInformation[0] - 1) );
|
||||
}
|
||||
else if (rec->ExceptionCode == DBG_PRINTEXCEPTION_WIDE_C)
|
||||
{
|
||||
WARN( "%s\n", debugstr_wn((WCHAR *)rec->ExceptionInformation[1], rec->ExceptionInformation[0] - 1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rec->ExceptionCode == STATUS_ASSERTION_FAILURE)
|
||||
ERR( "%s exception (code=%lx) raised\n", debugstr_exception_code(rec->ExceptionCode), rec->ExceptionCode );
|
||||
else
|
||||
WARN( "%s exception (code=%lx) raised\n", debugstr_exception_code(rec->ExceptionCode), rec->ExceptionCode );
|
||||
}
|
||||
|
||||
TRACE( "code=%lx flags=%lx addr=%p\n",
|
||||
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
|
||||
for (c = 0; c < min( EXCEPTION_MAXIMUM_PARAMETERS, rec->NumberParameters ); c++)
|
||||
TRACE( " info[%ld]=%016I64x\n", c, rec->ExceptionInformation[c] );
|
||||
TRACE_CONTEXT( context );
|
||||
|
||||
if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION)
|
||||
NtContinue( context, FALSE );
|
||||
|
||||
if ((status = call_stack_handlers( rec, context )) == STATUS_SUCCESS)
|
||||
NtContinue( context, FALSE );
|
||||
|
||||
if (status != STATUS_UNHANDLED_EXCEPTION) RtlRaiseStatus( status );
|
||||
return NtRaiseException( rec, context, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* KiUserExceptionDispatcher (NTDLL.@)
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue