/* * Unhandled Exception Filter * Top-level per-process exception handler. */ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) { EXCEPTION_RECORD* er; CONTEXT* ctx; LONG res; MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); /* If the thread is not managed by the runtime return early */ if (!jit_tls) return EXCEPTION_CONTINUE_SEARCH; jit_tls->mono_win_chained_exception_needs_run = FALSE; res = EXCEPTION_CONTINUE_EXECUTION; er = ep->ExceptionRecord; ctx = ep->ContextRecord; switch (er->ExceptionCode) { case EXCEPTION_STACK_OVERFLOW: win32_handle_stack_overflow (ep, ctx); break; case EXCEPTION_ACCESS_VIOLATION: W32_SEH_HANDLE_EX(segv); break; case EXCEPTION_ILLEGAL_INSTRUCTION: W32_SEH_HANDLE_EX(ill); break; case EXCEPTION_INT_DIVIDE_BY_ZERO: case EXCEPTION_INT_OVERFLOW: case EXCEPTION_FLT_DIVIDE_BY_ZERO: case EXCEPTION_FLT_OVERFLOW: case EXCEPTION_FLT_UNDERFLOW: case EXCEPTION_FLT_INEXACT_RESULT: W32_SEH_HANDLE_EX(fpe); break; default: jit_tls->mono_win_chained_exception_needs_run = TRUE; break; } if (jit_tls->mono_win_chained_exception_needs_run) { /* Don't copy context back if we chained exception * as the handler may have modfied the EXCEPTION_POINTERS * directly. We don't pass sigcontext to chained handlers. * Return continue search so the UnhandledExceptionFilter * can correctly chain the exception. */ res = EXCEPTION_CONTINUE_SEARCH; } return res; }
/* * Unhandled Exception Filter * Top-level per-process exception handler. */ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep) { EXCEPTION_RECORD* er; CONTEXT* ctx; struct sigcontext* sctx; LONG res; mono_win_chained_exception_filter_didrun = FALSE; res = EXCEPTION_CONTINUE_EXECUTION; er = ep->ExceptionRecord; ctx = ep->ContextRecord; sctx = g_malloc(sizeof(struct sigcontext)); /* Copy Win32 context to UNIX style context */ sctx->eax = ctx->Eax; sctx->ebx = ctx->Ebx; sctx->ecx = ctx->Ecx; sctx->edx = ctx->Edx; sctx->ebp = ctx->Ebp; sctx->esp = ctx->Esp; sctx->esi = ctx->Esi; sctx->edi = ctx->Edi; sctx->eip = ctx->Eip; switch (er->ExceptionCode) { case EXCEPTION_STACK_OVERFLOW: win32_handle_stack_overflow (ep, sctx); break; case EXCEPTION_ACCESS_VIOLATION: W32_SEH_HANDLE_EX(segv); break; case EXCEPTION_ILLEGAL_INSTRUCTION: W32_SEH_HANDLE_EX(ill); break; case EXCEPTION_INT_DIVIDE_BY_ZERO: case EXCEPTION_INT_OVERFLOW: case EXCEPTION_FLT_DIVIDE_BY_ZERO: case EXCEPTION_FLT_OVERFLOW: case EXCEPTION_FLT_UNDERFLOW: case EXCEPTION_FLT_INEXACT_RESULT: W32_SEH_HANDLE_EX(fpe); break; default: break; } /* Copy context back */ ctx->Eax = sctx->eax; ctx->Ebx = sctx->ebx; ctx->Ecx = sctx->ecx; ctx->Edx = sctx->edx; ctx->Ebp = sctx->ebp; ctx->Esp = sctx->esp; ctx->Esi = sctx->esi; ctx->Edi = sctx->edi; ctx->Eip = sctx->eip; g_free (sctx); if (mono_win_chained_exception_filter_didrun) res = mono_win_chained_exception_filter_result; return res; }
/* * Unhandled Exception Filter * Top-level per-process exception handler. */ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) { EXCEPTION_RECORD* er; CONTEXT* ctx; struct sigcontext* sctx; LONG res; mono_win_chained_exception_needs_run = FALSE; res = EXCEPTION_CONTINUE_EXECUTION; er = ep->ExceptionRecord; ctx = ep->ContextRecord; sctx = g_malloc(sizeof(struct sigcontext)); /* Copy Win32 context to UNIX style context */ sctx->eax = ctx->Eax; sctx->ebx = ctx->Ebx; sctx->ecx = ctx->Ecx; sctx->edx = ctx->Edx; sctx->ebp = ctx->Ebp; sctx->esp = ctx->Esp; sctx->esi = ctx->Esi; sctx->edi = ctx->Edi; sctx->eip = ctx->Eip; switch (er->ExceptionCode) { case EXCEPTION_STACK_OVERFLOW: win32_handle_stack_overflow (ep, sctx); break; case EXCEPTION_ACCESS_VIOLATION: W32_SEH_HANDLE_EX(segv); break; case EXCEPTION_ILLEGAL_INSTRUCTION: W32_SEH_HANDLE_EX(ill); break; case EXCEPTION_INT_DIVIDE_BY_ZERO: case EXCEPTION_INT_OVERFLOW: case EXCEPTION_FLT_DIVIDE_BY_ZERO: case EXCEPTION_FLT_OVERFLOW: case EXCEPTION_FLT_UNDERFLOW: case EXCEPTION_FLT_INEXACT_RESULT: W32_SEH_HANDLE_EX(fpe); break; default: break; } if (mono_win_chained_exception_needs_run) { /* Don't copy context back if we chained exception * as the handler may have modfied the EXCEPTION_POINTERS * directly. We don't pass sigcontext to chained handlers. * Return continue search so the UnhandledExceptionFilter * can correctly chain the exception. */ res = EXCEPTION_CONTINUE_SEARCH; } else { /* Copy context back */ ctx->Eax = sctx->eax; ctx->Ebx = sctx->ebx; ctx->Ecx = sctx->ecx; ctx->Edx = sctx->edx; ctx->Ebp = sctx->ebp; ctx->Esp = sctx->esp; ctx->Esi = sctx->esi; ctx->Edi = sctx->edi; ctx->Eip = sctx->eip; } /* TODO: Find right place to free this in stack overflow case */ if (er->ExceptionCode != EXCEPTION_STACK_OVERFLOW) g_free (sctx); return res; }
/* * Unhandled Exception Filter * Top-level per-process exception handler. */ LONG CALLBACK seh_handler(EXCEPTION_POINTERS* ep) { EXCEPTION_RECORD* er; CONTEXT* ctx; MonoContext* sctx; LONG res; mono_win_chained_exception_filter_didrun = FALSE; res = EXCEPTION_CONTINUE_EXECUTION; er = ep->ExceptionRecord; ctx = ep->ContextRecord; sctx = g_malloc(sizeof(MonoContext)); /* Copy Win32 context to UNIX style context */ sctx->rax = ctx->Rax; sctx->rbx = ctx->Rbx; sctx->rcx = ctx->Rcx; sctx->rdx = ctx->Rdx; sctx->rbp = ctx->Rbp; sctx->rsp = ctx->Rsp; sctx->rsi = ctx->Rsi; sctx->rdi = ctx->Rdi; sctx->rip = ctx->Rip; sctx->r12 = ctx->R12; sctx->r13 = ctx->R13; sctx->r14 = ctx->R14; sctx->r15 = ctx->R15; switch (er->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: W32_SEH_HANDLE_EX(segv); break; case EXCEPTION_ILLEGAL_INSTRUCTION: W32_SEH_HANDLE_EX(ill); break; case EXCEPTION_INT_DIVIDE_BY_ZERO: case EXCEPTION_INT_OVERFLOW: case EXCEPTION_FLT_DIVIDE_BY_ZERO: case EXCEPTION_FLT_OVERFLOW: case EXCEPTION_FLT_UNDERFLOW: case EXCEPTION_FLT_INEXACT_RESULT: W32_SEH_HANDLE_EX(fpe); break; default: break; } /* Copy context back */ /* Nonvolatile */ ctx->Rsp = sctx->rsp; ctx->Rdi = sctx->rdi; ctx->Rsi = sctx->rsi; ctx->Rbx = sctx->rbx; ctx->Rbp = sctx->rbp; ctx->R12 = sctx->r12; ctx->R13 = sctx->r13; ctx->R14 = sctx->r14; ctx->R15 = sctx->r15; ctx->Rip = sctx->rip; /* Volatile But should not matter?*/ ctx->Rax = sctx->rax; ctx->Rcx = sctx->rcx; ctx->Rdx = sctx->rdx; g_free (sctx); if (mono_win_chained_exception_filter_didrun) res = mono_win_chained_exception_filter_result; return res; }