X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-exceptions.c;h=b1132f9f26176d6de99e1939b646e2c3ab9e4662;hb=a21319d1cacfcaeeebff0c5ff16070f87dba34ba;hp=099e6e10dd03ccda34fd010318f18e52b37674e5;hpb=608fbb28a0036a599d0be8dfc3822d08c908bf85;p=mono.git diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index 099e6e10dd0..b1132f9f261 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -81,6 +81,10 @@ #include "mini-llvm-cpp.h" #endif +#ifdef TARGET_ARM +#include "mini-arm.h" +#endif + #ifndef MONO_ARCH_CONTEXT_DEF #define MONO_ARCH_CONTEXT_DEF #endif @@ -89,6 +93,20 @@ #define MONO_ARCH_STACK_GROWS_UP 0 #endif +/* + * Raw frame information is stored in MonoException.trace_ips as an IntPtr[]. + * This structure represents one entry. + * This should consists of pointers only. + */ +typedef struct +{ + gpointer ip; + gpointer generic_info; +} ExceptionTraceIp; + +/* Number of words in trace_ips belonging to one entry */ +#define TRACE_IP_ENTRY_SIZE (sizeof (ExceptionTraceIp) / sizeof (gpointer)) + static gpointer restore_context_func, call_filter_func; static gpointer throw_exception_func, rethrow_exception_func; static gpointer throw_corlib_exception_func; @@ -826,10 +844,13 @@ mono_exception_walk_trace (MonoException *ex, MonoExceptionFrameWalk func, gpoin if (ta == NULL) return FALSE; - len = mono_array_length (ta) >> 1; + len = mono_array_length (ta) / TRACE_IP_ENTRY_SIZE; for (i = 0; i < len; i++) { - gpointer ip = mono_array_get (ta, gpointer, i * 2 + 0); - gpointer generic_info = mono_array_get (ta, gpointer, i * 2 + 1); + ExceptionTraceIp trace_ip; + + memcpy (&trace_ip, mono_array_addr_fast (ta, ExceptionTraceIp, i), sizeof (ExceptionTraceIp)); + gpointer ip = trace_ip.ip; + gpointer generic_info = trace_ip.generic_info; MonoJitInfo *ji = mono_jit_info_table_find (domain, (char *)ip); if (ji == NULL) { @@ -862,7 +883,7 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info return res; } - len = mono_array_length (ta) >> 1; + len = mono_array_length (ta) / TRACE_IP_ENTRY_SIZE; res = mono_array_new_checked (domain, mono_defaults.stack_frame_class, len > skip ? len - skip : 0, &error); if (mono_error_set_pending_exception (&error)) @@ -875,8 +896,10 @@ ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info mono_error_set_pending_exception (&error); return NULL; } - gpointer ip = mono_array_get (ta, gpointer, i * 2 + 0); - gpointer generic_info = mono_array_get (ta, gpointer, i * 2 + 1); + ExceptionTraceIp trace_ip; + memcpy (&trace_ip, mono_array_addr_fast (ta, ExceptionTraceIp, i), sizeof (ExceptionTraceIp)); + gpointer ip = trace_ip.ip; + gpointer generic_info = trace_ip.generic_info; MonoMethod *method; ji = mono_jit_info_table_find (domain, (char *)ip); @@ -1066,6 +1089,7 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain mgreg_t *new_reg_locations [MONO_MAX_IREGS]; gboolean get_reg_locations = unwind_options & MONO_UNWIND_REG_LOCATIONS; gboolean async = mono_thread_info_is_async_context (); + Unwinder unwinder; if (mono_llvm_only) { GSList *l, *ips; @@ -1110,9 +1134,11 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoDomain memcpy (&ctx, start_ctx, sizeof (MonoContext)); memset (reg_locations, 0, sizeof (reg_locations)); + unwinder_init (&unwinder); + while (MONO_CONTEXT_GET_SP (&ctx) < jit_tls->end_of_stack) { frame.lmf = lmf; - res = mono_find_jit_info_ext (domain, jit_tls, NULL, &ctx, &new_ctx, NULL, &lmf, get_reg_locations ? new_reg_locations : NULL, &frame); + res = unwinder_unwind_frame (&unwinder, domain, jit_tls, NULL, &ctx, &new_ctx, NULL, &lmf, get_reg_locations ? new_reg_locations : NULL, &frame); if (!res) return; @@ -1559,13 +1585,13 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, MonoObject *obj, gi mono_ex = (MonoException*)obj; MonoArray *initial_trace_ips = mono_ex->trace_ips; if (initial_trace_ips) { - int len = mono_array_length (initial_trace_ips) >> 1; + int len = mono_array_length (initial_trace_ips) / TRACE_IP_ENTRY_SIZE; for (i = 0; i < (len - 1); i++) { - gpointer ip = mono_array_get (initial_trace_ips, gpointer, i * 2 + 0); - gpointer generic_info = mono_array_get (initial_trace_ips, gpointer, i * 2 + 1); - trace_ips = g_list_prepend (trace_ips, ip); - trace_ips = g_list_prepend (trace_ips, generic_info); + for (int j = 0; j < TRACE_IP_ENTRY_SIZE; ++j) { + gpointer p = mono_array_get (initial_trace_ips, gpointer, (i * TRACE_IP_ENTRY_SIZE) + j); + trace_ips = g_list_prepend (trace_ips, p); + } } } @@ -1629,7 +1655,7 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, MonoObject *obj, gi gpointer ip; if (in_interp) - ip = (guint16*)ji->code_start + frame.native_offset; + ip = (guint8*)ji->code_start + frame.native_offset; else ip = MONO_CONTEXT_GET_IP (ctx); @@ -2005,7 +2031,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu } if (in_interp) - ip = (guint16*)ji->code_start + frame.native_offset; + ip = (guint8*)ji->code_start + frame.native_offset; else ip = MONO_CONTEXT_GET_IP (ctx); @@ -2127,10 +2153,16 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu * like the call which transitioned to JITted code has succeeded, but the * return value register etc. is not set, so we have to be careful. */ - mono_interp_set_resume_state (mono_ex, &frame, ei->handler_start); + mono_interp_set_resume_state (jit_tls, mono_ex, frame.interp_frame, ei->handler_start); /* Undo the IP adjustment done by mono_arch_unwind_frame () */ -#ifdef TARGET_AMD64 +#if defined(TARGET_AMD64) ctx->gregs [AMD64_RIP] ++; +#elif defined(TARGET_ARM) + ctx->pc ++; + if (mono_arm_thumb_supported ()) + ctx->pc |= 1; +#elif defined(TARGET_ARM64) + ctx->pc ++; #else NOT_IMPLEMENTED; #endif @@ -2250,6 +2282,9 @@ mono_debugger_run_finally (MonoContext *start_ctx) * mono_handle_exception: * \param ctx saved processor state * \param obj the exception object + * + * Handle the exception OBJ starting from the state CTX. Modify CTX to point to the handler clause if the exception is caught, and + * return TRUE. */ gboolean mono_handle_exception (MonoContext *ctx, MonoObject *obj) @@ -2598,7 +2633,7 @@ static void print_process_map (void) #endif } -static gboolean handling_sigsegv = FALSE; +static gboolean handle_crash_loop = FALSE; /* * mono_handle_native_crash: @@ -2614,9 +2649,7 @@ mono_handle_native_crash (const char *signal, void *ctx, MONO_SIG_HANDLER_INFO_T #endif MonoJitTlsData *jit_tls = (MonoJitTlsData *)mono_tls_get_jit_tls (); - gboolean is_sigsegv = !strcmp ("SIGSEGV", signal); - - if (handling_sigsegv && is_sigsegv) + if (handle_crash_loop) return; if (mini_get_debug_options ()->suspend_on_native_crash) { @@ -2631,9 +2664,8 @@ mono_handle_native_crash (const char *signal, void *ctx, MONO_SIG_HANDLER_INFO_T #endif } - /* To prevent infinite loops when the stack walk causes a crash */ - if (is_sigsegv) - handling_sigsegv = TRUE; + /* prevent infinite loops in crash handling */ + handle_crash_loop = TRUE; /* !jit_tls means the thread was not registered with the runtime */ if (jit_tls && mono_thread_internal_current ()) { @@ -3271,12 +3303,12 @@ mono_llvm_load_exception (void) size_t upper = mono_array_length (mono_ex->trace_ips); - for (int i = 0; i < upper; i+= 2) { + for (int i = 0; i < upper; i += TRACE_IP_ENTRY_SIZE) { gpointer curr_ip = mono_array_get (mono_ex->trace_ips, gpointer, i); - gpointer curr_info = mono_array_get (mono_ex->trace_ips, gpointer, i + 1); - trace_ips = g_list_append (trace_ips, curr_ip); - trace_ips = g_list_append (trace_ips, curr_info); - + for (int j = 0; j < TRACE_IP_ENTRY_SIZE; ++j) { + gpointer p = mono_array_get (mono_ex->trace_ips, gpointer, i + j); + trace_ips = g_list_append (trace_ips, p); + } if (ip == curr_ip) break; } @@ -3397,31 +3429,3 @@ mono_debug_personality (void) g_assert_not_reached (); } #endif - -#ifndef ENABLE_INTERPRETER -/* Stubs of interpreter functions */ -void -mono_interp_set_resume_state (MonoException *ex, StackFrameInfo *frame, gpointer handler_ip) -{ - g_assert_not_reached (); -} - -void -mono_interp_run_finally (StackFrameInfo *frame, int clause_index, gpointer handler_ip) -{ - g_assert_not_reached (); -} - -void -mono_interp_frame_iter_init (MonoInterpStackIter *iter, gpointer interp_exit_data) -{ - g_assert_not_reached (); -} - -gboolean -mono_interp_frame_iter_next (MonoInterpStackIter *iter, StackFrameInfo *frame) -{ - g_assert_not_reached (); - return FALSE; -} -#endif