* Mono Team (mono-list@lists.ximian.com)
*
* Copyright 2001-2003 Ximian, Inc.
- * Copyright 2003-2008 Ximian, Inc.
+ * Copyright 2003-2011 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
*
* See LICENSE for licensing information.
*/
#include <dlfcn.h>
#include <AvailabilityMacros.h>
-#if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5) && !defined (TARGET_ARM)
+#if defined (TARGET_OSX) && (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5)
#define NEEDS_EXCEPTION_THREAD
#endif
/* The exception port */
static mach_port_t mach_exception_port = VM_MAP_NULL;
+kern_return_t
+catch_exception_raise (
+ mach_port_t exception_port,
+ mach_port_t thread,
+ mach_port_t task,
+ exception_type_t exception,
+ exception_data_t code,
+ mach_msg_type_number_t code_count);
+
/*
* Implicitly called by exc_server. Must be public.
*
MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL);
- g_assert (result == MACH_MSG_SUCCESS);
+ /*
+ If we try to abort the thread while delivering an exception. The port will be gone since the kernel
+ setup a send once port to deliver the resume message and thread_abort will consume it.
+ */
+ g_assert (result == MACH_MSG_SUCCESS || result == MACH_SEND_INVALID_DEST);
}
return NULL;
}
static void
-macosx_register_exception_handler ()
+macosx_register_exception_handler (void)
{
mach_port_t task;
pthread_attr_t attr;
/* This is #define'd by Boehm GC to _GC_dlopen. */
#undef dlopen
+void* dlopen(const char* path, int mode);
+
void
mono_runtime_install_handlers (void)
{
return (pid_t) fork ();
}
-gboolean
-mono_gdb_render_native_backtraces ()
+void
+mono_gdb_render_native_backtraces (pid_t crashed_pid)
{
const char *argv [5];
char gdb_template [] = "/tmp/mono-gdb-commands.XXXXXX";
argv [0] = g_find_program_in_path ("gdb");
if (argv [0] == NULL) {
- return FALSE;
+ return;
}
if (mkstemp (gdb_template) != -1) {
FILE *gdb_commands = fopen (gdb_template, "w");
- fprintf (gdb_commands, "attach %ld\n", (long) getpid ());
+ fprintf (gdb_commands, "attach %ld\n", (long) crashed_pid);
fprintf (gdb_commands, "info threads\n");
fprintf (gdb_commands, "thread apply all bt\n");
unlink (gdb_template);
}
-
- return TRUE;
}
gboolean
guint32 domain_key, jit_key;
MonoJitTlsData *jit_tls;
void *domain;
+#if defined (MONO_ARCH_ENABLE_MONO_LMF_VAR)
+ guint32 lmf_key;
+#endif
+
+ /*Zero enough state to make sure the caller doesn't confuse itself*/
+ tctx->valid = FALSE;
+ tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = NULL;
+ tctx->unwind_data [MONO_UNWIND_DATA_LMF] = NULL;
+ tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = NULL;
state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
mono_sigctx_to_monoctx (&ctx, &tctx->ctx);
- domain_key = mono_domain_get_tls_offset ();
+ domain_key = mono_domain_get_tls_key ();
jit_key = mono_get_jit_tls_key ();
+
jit_tls = mono_mach_arch_get_tls_value_from_thread (thread_id, jit_key);
domain = mono_mach_arch_get_tls_value_from_thread (thread_id, domain_key);
/*Thread already started to cleanup, can no longer capture unwind state*/
- if (!jit_tls)
+ if (!jit_tls || !domain)
return FALSE;
- g_assert (domain);
- tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = domain;
+#if defined (MONO_ARCH_ENABLE_MONO_LMF_VAR)
+ lmf_key = mono_get_lmf_tls_offset ();
+ tctx->unwind_data [MONO_UNWIND_DATA_LMF] = mono_mach_arch_get_tls_value_from_thread (thread_id, lmf_key);;
+#else
tctx->unwind_data [MONO_UNWIND_DATA_LMF] = jit_tls ? jit_tls->lmf : NULL;
+#endif
+
+ tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = domain;
tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = jit_tls;
tctx->valid = TRUE;