From 973c4d3882d8f51c7b80fbcaa8b51d5278e89f5a Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 22 Oct 2019 06:31:23 -0400 Subject: [PATCH] [jit] Avoid running mono_handle_native_crash () on the altstack, it can't produce a backtrace. AMD64 only for now. (mono/mono#17466) * [jit] Avoid running mono_handle_native_crash () on the altstack, it can't produce a backtrace. AMD64 only for now. * Fix checks so stack overflows work again. Commit migrated from https://github.com/mono/mono/commit/b96260e603fe0188e54019bfde8ca00bc2b5d78c --- src/mono/mono/mini/exceptions-amd64.c | 12 +++++++++--- src/mono/mono/mini/mini-runtime.c | 14 ++++++++++---- src/mono/mono/mini/mini-runtime.h | 3 +++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/mono/mono/mini/exceptions-amd64.c b/src/mono/mono/mini/exceptions-amd64.c index b274cc4..c301b90 100644 --- a/src/mono/mono/mini/exceptions-amd64.c +++ b/src/mono/mono/mini/exceptions-amd64.c @@ -867,12 +867,14 @@ prepare_for_guard_pages (MonoContext *mctx) } static void -altstack_handle_and_restore (MonoContext *ctx, MonoObject *obj, gboolean stack_ovf) +altstack_handle_and_restore (MonoContext *ctx, MonoObject *obj, guint32 flags) { MonoContext mctx; MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), MONO_CONTEXT_GET_IP (ctx), NULL); + gboolean stack_ovf = (flags & 1) != 0; + gboolean nullref = (flags & 2) != 0; - if (!ji) + if (!ji || (!stack_ovf && !nullref)) mono_handle_native_crash ("SIGSEGV", ctx, NULL); mctx = *ctx; @@ -894,6 +896,10 @@ mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *s gpointer *sp; int frame_size; MonoContext *copied_ctx; + gboolean nullref = TRUE; + + if (!mono_is_addr_implicit_null_check (fault_addr)) + nullref = FALSE; if (stack_ovf) exc = mono_domain_get ()->stack_overflow_ex; @@ -920,7 +926,7 @@ mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *s UCONTEXT_REG_RSP (sigctx) = (unsigned long)(sp - 1); UCONTEXT_REG_RDI (sigctx) = (unsigned long)(copied_ctx); UCONTEXT_REG_RSI (sigctx) = (guint64)exc; - UCONTEXT_REG_RDX (sigctx) = stack_ovf; + UCONTEXT_REG_RDX (sigctx) = (stack_ovf ? 1 : 0) | (nullref ? 2 : 0); #endif } diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index 0089cfb..f05af55 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -3274,8 +3274,8 @@ MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler) #endif -static gboolean -is_addr_implicit_null_check (void *addr) +gboolean +mono_is_addr_implicit_null_check (void *addr) { /* implicit null checks are only expected to work on the first page. larger * offsets are expected to have an explicit null check */ @@ -3365,11 +3365,17 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) if (!ji && mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) return; - if (is_addr_implicit_null_check (info->si_addr)) { +#ifdef TARGET_AMD64 + /* exceptions-amd64.c handles the check itself */ + mono_arch_handle_altstack_exception (ctx, info, info->si_addr, FALSE); +#else + if (mono_is_addr_implicit_null_check (info->si_addr)) { mono_arch_handle_altstack_exception (ctx, info, info->si_addr, FALSE); } else { + // FIXME: This shouldn't run on the altstack mono_handle_native_crash ("SIGSEGV", &mctx, info); } +#endif } #else @@ -3385,7 +3391,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) } } - if (is_addr_implicit_null_check (fault_addr)) { + if (mono_is_addr_implicit_null_check (fault_addr)) { mono_arch_handle_exception (ctx, NULL); } else { mono_handle_native_crash ("SIGSEGV", &mctx, (MONO_SIG_HANDLER_INFO_TYPE*)info); diff --git a/src/mono/mono/mini/mini-runtime.h b/src/mono/mono/mini/mini-runtime.h index 8cb8213..3981e77 100644 --- a/src/mono/mono/mini/mini-runtime.h +++ b/src/mono/mono/mini/mini-runtime.h @@ -558,6 +558,9 @@ mono_dump_native_crash_info (const char *signal, MonoContext *mctx, MONO_SIG_HAN void mono_post_native_crash_handler (const char *signal, MonoContext *mctx, MONO_SIG_HANDLER_INFO_TYPE *info, gboolean crash_chaining); +gboolean +mono_is_addr_implicit_null_check (void *addr); + /* * Signal handling */ -- 2.7.4