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"
|
#include "ntdll_misc.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||||
|
WINE_DECLARE_DEBUG_CHANNEL(threadname);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -58,7 +59,7 @@ static RTL_CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0
|
||||||
|
|
||||||
static PRTL_EXCEPTION_FILTER unhandled_exception_filter;
|
static PRTL_EXCEPTION_FILTER unhandled_exception_filter;
|
||||||
|
|
||||||
const char *debugstr_exception_code( DWORD code )
|
static const char *debugstr_exception_code( DWORD code )
|
||||||
{
|
{
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
|
@ -143,7 +144,7 @@ static ULONG remove_vectored_handler( struct list *handler_list, VECTORED_HANDLE
|
||||||
*
|
*
|
||||||
* Call the vectored handlers chain.
|
* 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;
|
struct list *ptr;
|
||||||
LONG ret = EXCEPTION_CONTINUE_SEARCH;
|
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__)
|
#if defined(__WINE_PE_BUILD) && !defined(__i386__)
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
|
|
@ -60,7 +60,8 @@ extern UINT_PTR page_size;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* exceptions */
|
/* 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 NTSTATUS WINAPI dispatch_user_callback( void *args, ULONG len, ULONG id );
|
||||||
extern EXCEPTION_DISPOSITION WINAPI user_callback_handler( EXCEPTION_RECORD *record, void *frame,
|
extern EXCEPTION_DISPOSITION WINAPI user_callback_handler( EXCEPTION_RECORD *record, void *frame,
|
||||||
CONTEXT *context, void *dispatch );
|
CONTEXT *context, void *dispatch );
|
||||||
|
@ -86,7 +87,6 @@ extern void (WINAPI *pWow64PrepareForException)( EXCEPTION_RECORD *rec, CONTEXT
|
||||||
|
|
||||||
/* debug helpers */
|
/* debug helpers */
|
||||||
extern LPCSTR debugstr_us( const UNICODE_STRING *str );
|
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 );
|
extern void set_native_thread_name( DWORD tid, const char *name );
|
||||||
|
|
||||||
/* init routines */
|
/* init routines */
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(threadname);
|
|
||||||
|
|
||||||
|
|
||||||
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
|
/* 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;
|
EXCEPTION_REGISTRATION_RECORD *teb_frame = NtCurrentTeb()->Tib.ExceptionList;
|
||||||
UNWIND_HISTORY_TABLE table;
|
UNWIND_HISTORY_TABLE table;
|
||||||
|
@ -441,64 +440,6 @@ static NTSTATUS call_function_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_con
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* KiUserExceptionDispatcher (NTDLL.@)
|
* 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_GLOBAL_FUNC( KiUserExceptionDispatcher,
|
||||||
__ASM_SEH(".seh_custom 0xee,0x02\n\t") /* MSFT_OP_CONTEXT */
|
__ASM_SEH(".seh_custom 0xee,0x02\n\t") /* MSFT_OP_CONTEXT */
|
||||||
__ASM_SEH(".seh_endprologue\n\t")
|
__ASM_SEH(".seh_endprologue\n\t")
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(threadname);
|
|
||||||
|
|
||||||
|
|
||||||
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
|
/* 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;
|
EXCEPTION_REGISTRATION_RECORD *teb_frame = NtCurrentTeb()->Tib.ExceptionList;
|
||||||
UNWIND_HISTORY_TABLE table;
|
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.@)
|
* KiUserExceptionDispatcher (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(threadname);
|
|
||||||
|
|
||||||
struct x86_thread_data
|
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;
|
EXCEPTION_REGISTRATION_RECORD *frame, *dispatch, *nested_frame;
|
||||||
DWORD res;
|
DWORD res;
|
||||||
|
@ -195,64 +194,6 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* KiUserExceptionDispatcher (NTDLL.@)
|
* 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,
|
__ASM_STDCALL_FUNC( KiUserExceptionDispatcher, 8,
|
||||||
"pushl 4(%esp)\n\t"
|
"pushl 4(%esp)\n\t"
|
||||||
"pushl 4(%esp)\n\t"
|
"pushl 4(%esp)\n\t"
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
WINE_DEFAULT_DEBUG_CHANNEL(seh);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(threadname);
|
|
||||||
|
|
||||||
|
|
||||||
/* layering violation: the setjmp buffer is defined in msvcrt, but used by RtlUnwindEx */
|
/* 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;
|
EXCEPTION_REGISTRATION_RECORD *teb_frame = NtCurrentTeb()->Tib.ExceptionList;
|
||||||
UNWIND_HISTORY_TABLE table;
|
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.@)
|
* KiUserExceptionDispatcher (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue