X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-windows.c;h=9488ac895d991570879327ed2b2db009742fc89b;hb=69ba0b04fd7f45f303da4cd537b1a2b158b5fd75;hp=0530509d23fba0db0cd38bc7a6037019cd904d96;hpb=b7188daad8bfd29353ab228b9200537897b23c9e;p=mono.git diff --git a/mono/mini/mini-windows.c b/mono/mini/mini-windows.c index 0530509d23f..9488ac895d9 100644 --- a/mono/mini/mini-windows.c +++ b/mono/mini/mini-windows.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include @@ -53,24 +53,37 @@ void mono_runtime_install_handlers (void) { +#ifndef MONO_CROSS_COMPILE win32_seh_init(); win32_seh_set_handler(SIGFPE, mono_sigfpe_signal_handler); win32_seh_set_handler(SIGILL, mono_sigill_signal_handler); win32_seh_set_handler(SIGSEGV, mono_sigsegv_signal_handler); if (mini_get_debug_options ()->handle_sigint) win32_seh_set_handler(SIGINT, mono_sigint_signal_handler); +#endif } void mono_runtime_cleanup_handlers (void) { +#ifndef MONO_CROSS_COMPILE win32_seh_cleanup(); +#endif } + +/* mono_chain_signal: + * + * Call the original signal handler for the signal given by the arguments, which + * should be the same as for a signal handler. Returns TRUE if the original handler + * was called, false otherwise. + */ gboolean -SIG_HANDLER_SIGNATURE (mono_chain_signal) +MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) { - return FALSE; + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); + jit_tls->mono_win_chained_exception_needs_run = TRUE; + return TRUE; } static HANDLE win32_main_thread; @@ -110,7 +123,7 @@ mono_runtime_setup_stat_profiler (void) if (timeBeginPeriod (1) != TIMERR_NOERROR) return; - if ((win32_timer = timeSetEvent (1, 0, win32_time_proc, 0, TIME_PERIODIC)) == 0) { + if ((win32_timer = timeSetEvent (1, 0, (LPTIMECALLBACK)win32_time_proc, (DWORD_PTR)NULL, TIME_PERIODIC)) == 0) { timeEndPeriod (1); return; } @@ -120,3 +133,69 @@ void mono_runtime_shutdown_stat_profiler (void) { } + +gboolean +mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info) +{ + DWORD id = mono_thread_info_get_tid (info); + HANDLE handle; + CONTEXT context; + DWORD result; + MonoContext *ctx; + MonoJitTlsData *jit_tls; + void *domain; + MonoLMF *lmf = NULL; + gpointer *addr; + + 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; + + g_assert (id != GetCurrentThreadId ()); + + handle = OpenThread (THREAD_ALL_ACCESS, FALSE, id); + g_assert (handle); + + context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL; + + if (!GetThreadContext (handle, &context)) { + CloseHandle (handle); + return FALSE; + } + + g_assert (context.ContextFlags & CONTEXT_INTEGER); + g_assert (context.ContextFlags & CONTEXT_CONTROL); + + ctx = &tctx->ctx; + + memset (ctx, 0, sizeof (MonoContext)); + mono_sigctx_to_monoctx (&context, ctx); + + /* mono_set_jit_tls () sets this */ + jit_tls = mono_thread_info_tls_get (info, TLS_KEY_JIT_TLS); + /* SET_APPDOMAIN () sets this */ + domain = mono_thread_info_tls_get (info, TLS_KEY_DOMAIN); + + /*Thread already started to cleanup, can no longer capture unwind state*/ + if (!jit_tls || !domain) + return FALSE; + + /* + * The current LMF address is kept in a separate TLS variable, and its hard to read its value without + * arch-specific code. But the address of the TLS variable is stored in another TLS variable which + * can be accessed through MonoThreadInfo. + */ + /* mono_set_lmf_addr () sets this */ + addr = mono_thread_info_tls_get (info, TLS_KEY_LMF_ADDR); + if (addr) + lmf = *addr; + + tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = domain; + tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = jit_tls; + tctx->unwind_data [MONO_UNWIND_DATA_LMF] = lmf; + tctx->valid = TRUE; + + return TRUE; +} +