提交 efae6c06 编写于 作者: L Lucas Meijer

Implement signal chaining for windows. Useful for letting custom crash...

Implement signal chaining for windows. Useful for letting custom crash reporters be able to deal with native crashes, without mono eating the native exception while checking to see if it was caused by a managed null dereference in jitted code or not.
上级 be07f04c
......@@ -38,10 +38,12 @@ static MonoW32ExceptionHandler fpe_handler;
static MonoW32ExceptionHandler ill_handler;
static MonoW32ExceptionHandler segv_handler;
static LPTOP_LEVEL_EXCEPTION_FILTER old_handler;
LPTOP_LEVEL_EXCEPTION_FILTER old_win_toplevel_exception_filter;
guint64 win_chained_exception_filter_result;
gboolean win_chained_exception_filter_didrun;
#define W32_SEH_HANDLE_EX(_ex) \
if (_ex##_handler) _ex##_handler(0, er, sctx)
if (_ex##_handler) _ex##_handler(0, ep, sctx)
/*
* Unhandled Exception Filter
......@@ -54,6 +56,7 @@ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep)
MonoContext* sctx;
LONG res;
win_chained_exception_filter_didrun = FALSE;
res = EXCEPTION_CONTINUE_EXECUTION;
er = ep->ExceptionRecord;
......@@ -114,17 +117,20 @@ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep)
g_free (sctx);
if (win_chained_exception_filter_didrun)
res = win_chained_exception_filter_result;
return res;
}
void win32_seh_init()
{
old_handler = SetUnhandledExceptionFilter(seh_handler);
old_win_toplevel_exception_filter = SetUnhandledExceptionFilter(seh_handler);
}
void win32_seh_cleanup()
{
if (old_handler) SetUnhandledExceptionFilter(old_handler);
if (old_win_toplevel_exception_filter) SetUnhandledExceptionFilter(old_win_toplevel_exception_filter);
}
void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler)
......
......@@ -39,14 +39,16 @@ static MonoW32ExceptionHandler fpe_handler;
static MonoW32ExceptionHandler ill_handler;
static MonoW32ExceptionHandler segv_handler;
static LPTOP_LEVEL_EXCEPTION_FILTER old_handler;
LPTOP_LEVEL_EXCEPTION_FILTER old_win_toplevel_exception_filter;
guint64 win_chained_exception_filter_result;
gboolean win_chained_exception_filter_didrun;
#ifndef PROCESS_CALLBACK_FILTER_ENABLED
# define PROCESS_CALLBACK_FILTER_ENABLED 1
#endif
#define W32_SEH_HANDLE_EX(_ex) \
if (_ex##_handler) _ex##_handler(0, er, sctx)
if (_ex##_handler) _ex##_handler(0, ep, sctx)
/*
* mono_win32_get_handle_stackoverflow (void):
......@@ -176,6 +178,7 @@ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep)
struct sigcontext* sctx;
LONG res;
win_chained_exception_filter_didrun = FALSE;
res = EXCEPTION_CONTINUE_EXECUTION;
er = ep->ExceptionRecord;
......@@ -228,6 +231,9 @@ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep)
g_free (sctx);
if (win_chained_exception_filter_didrun)
res = win_chained_exception_filter_result;
return res;
}
......@@ -237,12 +243,12 @@ void win32_seh_init()
if (!restore_stack)
restore_stack = mono_win32_get_handle_stackoverflow ();
old_handler = SetUnhandledExceptionFilter(seh_handler);
old_win_toplevel_exception_filter = SetUnhandledExceptionFilter(seh_handler);
}
void win32_seh_cleanup()
{
if (old_handler) SetUnhandledExceptionFilter(old_handler);
if (old_win_toplevel_exception_filter) SetUnhandledExceptionFilter(old_win_toplevel_exception_filter);
}
void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler)
......
......@@ -50,6 +50,10 @@
#include "jit-icalls.h"
extern LPTOP_LEVEL_EXCEPTION_FILTER old_win_toplevel_exception_filter;
extern guint64 win_chained_exception_filter_result;
extern gboolean win_chained_exception_filter_didrun;
void
mono_runtime_install_handlers (void)
{
......@@ -71,9 +75,24 @@ mono_runtime_cleanup_handlers (void)
#endif
}
/* mono_chain_signal:
*
* Call the original signal handler for the signal given by the arguments, which
* should be the same as for a signal handler. Returns TRUE if the original handler
* was called, false otherwise.
*/
gboolean
SIG_HANDLER_SIGNATURE (mono_chain_signal)
{
int signal = _dummy;
GET_CONTEXT;
if (old_win_toplevel_exception_filter) {
win_chained_exception_filter_didrun = TRUE;
win_chained_exception_filter_result = (*old_win_toplevel_exception_filter)(info);
return TRUE;
}
return FALSE;
}
......
......@@ -6443,7 +6443,8 @@ gboolean
mono_arch_is_single_step_event (void *info, void *sigctx)
{
#ifdef TARGET_WIN32
EXCEPTION_RECORD* einfo = (EXCEPTION_RECORD*)info; /* Sometimes the address is off by 4 */
EXCEPTION_RECORD* einfo = ((EXCEPTION_POINTERS*)info)->ExceptionRecord; /* Sometimes the address is off by 4 */
if ((einfo->ExceptionInformation[1] >= ss_trigger_page && (guint8*)einfo->ExceptionInformation[1] <= (guint8*)ss_trigger_page + 128))
return TRUE;
else
......@@ -6462,7 +6463,7 @@ gboolean
mono_arch_is_breakpoint_event (void *info, void *sigctx)
{
#ifdef TARGET_WIN32
EXCEPTION_RECORD* einfo = (EXCEPTION_RECORD*)info; /* Sometimes the address is off by 4 */
EXCEPTION_RECORD* einfo = ((EXCEPTION_POINTERS*)info)->ExceptionRecord; /* Sometimes the address is off by 4 */
if ((einfo->ExceptionInformation[1] >= bp_trigger_page && (guint8*)einfo->ExceptionInformation[1] <= (guint8*)bp_trigger_page + 128))
return TRUE;
else
......
......@@ -31,7 +31,7 @@ struct sigcontext {
unsigned int eip;
};
typedef void (* MonoW32ExceptionHandler) (int _dummy, EXCEPTION_RECORD *info, void *context);
typedef void (* MonoW32ExceptionHandler) (int _dummy, EXCEPTION_POINTERS *info, void *context);
void win32_seh_init(void);
void win32_seh_cleanup(void);
void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler);
......
......@@ -2411,7 +2411,7 @@ gboolean mono_gdb_render_native_backtraces (void) MONO_INTERNAL;
#define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, siginfo_t *info, void *context)
#define SIG_HANDLER_PARAMS _dummy, info, context
#elif defined(HOST_WIN32)
#define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, EXCEPTION_RECORD *info, void *context)
#define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, EXCEPTION_POINTERS *info, void *context)
#define SIG_HANDLER_PARAMS _dummy, info, context
#elif defined(__HAIKU__)
#define SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, void *userData, vregs regs)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册