void mono_error_cleanup (MonoError *oerror) { // This function is called a lot so it is optimized. MonoErrorInternal *error = (MonoErrorInternal*)oerror; #if G_BYTE_ORDER == G_LITTLE_ENDIAN const guint32 init = oerror->init; const guint16 error_code = (guint16)(init & 0xFFFF); const guint16 error_flags = (guint16)(init >> 16); #else const guint16 error_code = error->error_code; const guint16 error_flags = error->flags; #endif /* Two cleanups in a row without an intervening init. */ g_assert (error_code != MONO_ERROR_CLEANUP_CALLED_SENTINEL); /* Mempool stored error shouldn't be cleaned up */ g_assert (!is_boxed_error_flags (error_flags)); /* Mark it as cleaned up. */ #if G_BYTE_ORDER == G_LITTLE_ENDIAN oerror->init = MONO_ERROR_CLEANUP_CALLED_SENTINEL; #else error->error_code = MONO_ERROR_CLEANUP_CALLED_SENTINEL; error->flags = 0; #endif if (error_code == MONO_ERROR_NONE) return; if (is_managed_error_code (error_code)) mono_gchandle_free_internal (error->exn.instance_handle); mono_error_free_string (&error->full_message); mono_error_free_string (&error->full_message_with_fields); if (!(error_flags & MONO_ERROR_FREE_STRINGS)) //no memory was allocated return; mono_error_free_string (&error->type_name); mono_error_free_string (&error->assembly_name); mono_error_free_string (&error->member_name); mono_error_free_string (&error->exception_name_space); mono_error_free_string (&error->exception_name); mono_error_free_string (&error->first_argument); error->exn.klass = NULL; }
char * mono_exception_handle_get_native_backtrace (MonoExceptionHandle exc) { #ifdef HAVE_BACKTRACE_SYMBOLS MonoDomain *domain; MonoArrayHandle arr = MONO_HANDLE_NEW(MonoArray, NULL); int i, len; GString *text; char **messages; MONO_HANDLE_GET (arr, exc, native_trace_ips); if (MONO_HANDLE_IS_NULL(arr)) return g_strdup (""); domain = mono_domain_get (); len = mono_array_handle_length (arr); text = g_string_new_len (NULL, len * 20); uint32_t gchandle; gpointer *addr = MONO_ARRAY_HANDLE_PIN (arr, gpointer, 0, &gchandle); MONO_ENTER_GC_SAFE; messages = backtrace_symbols (addr, len); MONO_EXIT_GC_SAFE; mono_gchandle_free_internal (gchandle); for (i = 0; i < len; ++i) { gpointer ip; MONO_HANDLE_ARRAY_GETVAL (ip, arr, gpointer, i); MonoJitInfo *ji = mono_jit_info_table_find (domain, ip); if (ji) { char *msg = mono_debug_print_stack_frame (mono_jit_info_get_method (ji), (char*)ip - (char*)ji->code_start, domain); g_string_append_printf (text, "%s\n", msg); g_free (msg); } else { g_string_append_printf (text, "%s\n", messages [i]); } } g_free (messages); return g_string_free (text, FALSE); #else return g_strdup (""); #endif }