提交 ab005362 编写于 作者: J Jonathan Chambers

Fix reentrant exception handling.

Store handled status in local that is passed into
handler rather than a single thread local value
which can be overwritten in case of reentrance.
上级 886cdece
...@@ -58,7 +58,7 @@ LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter; ...@@ -58,7 +58,7 @@ LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter;
void *mono_win_vectored_exception_handle; void *mono_win_vectored_exception_handle;
#define W32_SEH_HANDLE_EX(_ex) \ #define W32_SEH_HANDLE_EX(_ex) \
if (_ex##_handler) _ex##_handler(0, ep, ctx) if (_ex##_handler) _ex##_handler(er->ExceptionCode, &info, ctx)
static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep) static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
{ {
...@@ -137,12 +137,12 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) ...@@ -137,12 +137,12 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
LONG res; LONG res;
MonoJitTlsData *jit_tls = mono_tls_get_jit_tls (); MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
MonoDomain* domain = mono_domain_get (); MonoDomain* domain = mono_domain_get ();
MonoWindowsSigHandlerInfo info = { TRUE, ep };
/* If the thread is not managed by the runtime return early */ /* If the thread is not managed by the runtime return early */
if (!jit_tls) if (!jit_tls)
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
jit_tls->mono_win_chained_exception_needs_run = FALSE;
res = EXCEPTION_CONTINUE_EXECUTION; res = EXCEPTION_CONTINUE_EXECUTION;
er = ep->ExceptionRecord; er = ep->ExceptionRecord;
...@@ -159,7 +159,7 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) ...@@ -159,7 +159,7 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
ctx->Rip = (guint64)restore_stack; ctx->Rip = (guint64)restore_stack;
} }
} else { } else {
jit_tls->mono_win_chained_exception_needs_run = TRUE; info.handled = FALSE;
} }
break; break;
case EXCEPTION_ACCESS_VIOLATION: case EXCEPTION_ACCESS_VIOLATION:
...@@ -177,11 +177,11 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) ...@@ -177,11 +177,11 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
W32_SEH_HANDLE_EX(fpe); W32_SEH_HANDLE_EX(fpe);
break; break;
default: default:
jit_tls->mono_win_chained_exception_needs_run = TRUE; info.handled = FALSE;
break; break;
} }
if (jit_tls->mono_win_chained_exception_needs_run) { if (!info.handled) {
/* Don't copy context back if we chained exception /* Don't copy context back if we chained exception
* as the handler may have modfied the EXCEPTION_POINTERS * as the handler may have modfied the EXCEPTION_POINTERS
* directly. We don't pass sigcontext to chained handlers. * directly. We don't pass sigcontext to chained handlers.
......
...@@ -55,7 +55,7 @@ extern int (*gUnhandledExceptionHandler)(EXCEPTION_POINTERS*); ...@@ -55,7 +55,7 @@ extern int (*gUnhandledExceptionHandler)(EXCEPTION_POINTERS*);
#endif #endif
#define W32_SEH_HANDLE_EX(_ex) \ #define W32_SEH_HANDLE_EX(_ex) \
if (_ex##_handler) _ex##_handler(0, ep, ctx) if (_ex##_handler) _ex##_handler(er->ExceptionCode, &info, ctx)
LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep) LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
{ {
...@@ -198,12 +198,12 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) ...@@ -198,12 +198,12 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
CONTEXT* ctx; CONTEXT* ctx;
LONG res; LONG res;
MonoJitTlsData *jit_tls = mono_tls_get_jit_tls (); MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
MonoWindowsSigHandlerInfo info = { TRUE, ep };
/* If the thread is not managed by the runtime return early */ /* If the thread is not managed by the runtime return early */
if (!jit_tls) if (!jit_tls)
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
jit_tls->mono_win_chained_exception_needs_run = FALSE;
res = EXCEPTION_CONTINUE_EXECUTION; res = EXCEPTION_CONTINUE_EXECUTION;
er = ep->ExceptionRecord; er = ep->ExceptionRecord;
...@@ -228,11 +228,11 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) ...@@ -228,11 +228,11 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
W32_SEH_HANDLE_EX(fpe); W32_SEH_HANDLE_EX(fpe);
break; break;
default: default:
jit_tls->mono_win_chained_exception_needs_run = TRUE; info.handled = FALSE;
break; break;
} }
if (jit_tls->mono_win_chained_exception_needs_run) { if (!info.handled) {
/* Don't copy context back if we chained exception /* Don't copy context back if we chained exception
* as the handler may have modfied the EXCEPTION_POINTERS * as the handler may have modfied the EXCEPTION_POINTERS
* directly. We don't pass sigcontext to chained handlers. * directly. We don't pass sigcontext to chained handlers.
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <mono/arch/amd64/amd64-codegen.h> #include <mono/arch/amd64/amd64-codegen.h>
#include <mono/utils/mono-sigcontext.h> #include <mono/utils/mono-sigcontext.h>
#include <mono/utils/mono-signal-handler.h>
#include <mono/utils/mono-context.h> #include <mono/utils/mono-context.h>
#include <glib.h> #include <glib.h>
...@@ -32,7 +33,7 @@ struct sigcontext { ...@@ -32,7 +33,7 @@ struct sigcontext {
}; };
#endif #endif
typedef void (* MonoW32ExceptionHandler) (int _dummy, EXCEPTION_POINTERS *info, void *context); typedef void MONO_SIG_HANDLER_SIGNATURE ((*MonoW32ExceptionHandler));
void win32_seh_init(void); void win32_seh_init(void);
void win32_seh_cleanup(void); void win32_seh_cleanup(void);
void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler); void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler);
......
...@@ -101,11 +101,6 @@ struct MonoJitTlsData { ...@@ -101,11 +101,6 @@ struct MonoJitTlsData {
MonoContext orig_ex_ctx; MonoContext orig_ex_ctx;
gboolean orig_ex_ctx_set; gboolean orig_ex_ctx_set;
/*
* Stores if we need to run a chained exception in Windows.
*/
gboolean mono_win_chained_exception_needs_run;
/* /*
* The current exception in flight * The current exception in flight
*/ */
......
...@@ -255,8 +255,8 @@ mono_runtime_cleanup_handlers (void) ...@@ -255,8 +255,8 @@ mono_runtime_cleanup_handlers (void)
gboolean gboolean
MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal)
{ {
MonoJitTlsData *jit_tls = mono_tls_get_jit_tls (); /* Set to FALSE to indicate that vectored exception handling should continue to look for handler */
jit_tls->mono_win_chained_exception_needs_run = TRUE; MONO_SIG_HANDLER_GET_INFO ()->handled = FALSE;
return TRUE; return TRUE;
} }
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <signal.h> #include <signal.h>
#endif #endif
typedef void (* MonoW32ExceptionHandler) (int _dummy, EXCEPTION_POINTERS *info, void *context); typedef void MONO_SIG_HANDLER_SIGNATURE ((*MonoW32ExceptionHandler));
void win32_seh_init(void); void win32_seh_init(void);
void win32_seh_cleanup(void); void win32_seh_cleanup(void);
......
...@@ -78,12 +78,20 @@ ...@@ -78,12 +78,20 @@
*/ */
#ifdef HOST_WIN32 #ifdef HOST_WIN32
#define MONO_SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, EXCEPTION_POINTERS *_info, void *context) #define MONO_SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, MonoWindowsSigHandlerInfo *_info, void *context)
#define MONO_SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, EXCEPTION_POINTERS *_info, void *context)) #define MONO_SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, MonoWindowsSigHandlerInfo *_info, void *context))
#define MONO_SIG_HANDLER_PARAMS _dummy, _info, context #define MONO_SIG_HANDLER_PARAMS _dummy, _info, context
#define MONO_SIG_HANDLER_GET_SIGNO() (_dummy) #define MONO_SIG_HANDLER_GET_SIGNO() (0)
#define MONO_SIG_HANDLER_GET_INFO() (_info) #define MONO_SIG_HANDLER_GET_INFO() (_info)
#define MONO_SIG_HANDLER_INFO_TYPE EXCEPTION_POINTERS #define MONO_SIG_HANDLER_INFO_TYPE MonoWindowsSigHandlerInfo
typedef struct {
/* Set to FALSE to indicate chained signal handler needs run.
* With vectored exceptions Windows does that for us by returning
* EXCEPTION_CONTINUE_SEARCH from handler */
gboolean handled;
EXCEPTION_POINTERS* ep;
} MonoWindowsSigHandlerInfo;
/* seh_vectored_exception_handler () passes in a CONTEXT* */ /* seh_vectored_exception_handler () passes in a CONTEXT* */
#define MONO_SIG_HANDLER_GET_CONTEXT \ #define MONO_SIG_HANDLER_GET_CONTEXT \
void *ctx = context; void *ctx = context;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册