2 * mini-posix.c: POSIX signal handling support for Mono.
5 * Mono Team (mono-list@lists.ximian.com)
7 * Copyright 2001-2003 Ximian, Inc.
8 * Copyright 2003-2008 Ximian, Inc.
10 * See LICENSE for licensing information.
16 #include <mono/metadata/assembly.h>
17 #include <mono/metadata/loader.h>
18 #include <mono/metadata/tabledefs.h>
19 #include <mono/metadata/class.h>
20 #include <mono/metadata/object.h>
21 #include <mono/metadata/tokentype.h>
22 #include <mono/metadata/tabledefs.h>
23 #include <mono/metadata/threads.h>
24 #include <mono/metadata/appdomain.h>
25 #include <mono/metadata/debug-helpers.h>
26 #include <mono/io-layer/io-layer.h>
27 #include "mono/metadata/profiler.h"
28 #include <mono/metadata/profiler-private.h>
29 #include <mono/metadata/mono-config.h>
30 #include <mono/metadata/environment.h>
31 #include <mono/metadata/mono-debug.h>
32 #include <mono/metadata/gc-internal.h>
33 #include <mono/metadata/threads-types.h>
34 #include <mono/metadata/verify.h>
35 #include <mono/metadata/verify-internals.h>
36 #include <mono/metadata/mempool-internals.h>
37 #include <mono/metadata/attach.h>
38 #include <mono/utils/mono-math.h>
39 #include <mono/utils/mono-compiler.h>
40 #include <mono/utils/mono-counters.h>
41 #include <mono/utils/mono-logger-internal.h>
42 #include <mono/utils/mono-mmap.h>
43 #include <mono/utils/dtrace.h>
51 #include "jit-icalls.h"
54 mono_runtime_install_handlers (void)
56 #ifndef MONO_CROSS_COMPILE
58 win32_seh_set_handler(SIGFPE, mono_sigfpe_signal_handler);
59 win32_seh_set_handler(SIGILL, mono_sigill_signal_handler);
60 win32_seh_set_handler(SIGSEGV, mono_sigsegv_signal_handler);
61 if (mini_get_debug_options ()->handle_sigint)
62 win32_seh_set_handler(SIGINT, mono_sigint_signal_handler);
67 mono_runtime_cleanup_handlers (void)
69 #ifndef MONO_CROSS_COMPILE
77 * Call the original signal handler for the signal given by the arguments, which
78 * should be the same as for a signal handler. Returns TRUE if the original handler
79 * was called, false otherwise.
82 SIG_HANDLER_SIGNATURE (mono_chain_signal)
84 MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
85 jit_tls->mono_win_chained_exception_needs_run = TRUE;
89 static HANDLE win32_main_thread;
90 static MMRESULT win32_timer;
93 win32_time_proc (UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
97 context.ContextFlags = CONTEXT_CONTROL;
98 if (GetThreadContext (win32_main_thread, &context)) {
100 mono_profiler_stat_hit ((guchar *) context.Rip, &context);
102 mono_profiler_stat_hit ((guchar *) context.Eip, &context);
108 mono_runtime_setup_stat_profiler (void)
110 static int inited = 0;
117 if (timeGetDevCaps (&timecaps, sizeof (timecaps)) != TIMERR_NOERROR)
120 if ((win32_main_thread = OpenThread (READ_CONTROL | THREAD_GET_CONTEXT, FALSE, GetCurrentThreadId ())) == NULL)
123 if (timeBeginPeriod (1) != TIMERR_NOERROR)
126 if ((win32_timer = timeSetEvent (1, 0, (LPTIMECALLBACK)win32_time_proc, (DWORD_PTR)NULL, TIME_PERIODIC)) == 0) {
133 mono_runtime_shutdown_stat_profiler (void)
138 mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info)
140 DWORD id = mono_thread_info_get_tid (info);
145 MonoJitTlsData *jit_tls;
151 tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = NULL;
152 tctx->unwind_data [MONO_UNWIND_DATA_LMF] = NULL;
153 tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = NULL;
155 g_assert (id != GetCurrentThreadId ());
157 handle = OpenThread (THREAD_ALL_ACCESS, FALSE, id);
160 context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
162 if (!GetThreadContext (handle, &context)) {
163 CloseHandle (handle);
167 g_assert (context.ContextFlags & CONTEXT_INTEGER);
168 g_assert (context.ContextFlags & CONTEXT_CONTROL);
172 memset (ctx, 0, sizeof (MonoContext));
173 mono_sigctx_to_monoctx (&context, ctx);
175 /* mono_set_jit_tls () sets this */
176 jit_tls = mono_thread_info_tls_get (info, TLS_KEY_JIT_TLS);
177 /* SET_APPDOMAIN () sets this */
178 domain = mono_thread_info_tls_get (info, TLS_KEY_DOMAIN);
180 /*Thread already started to cleanup, can no longer capture unwind state*/
181 if (!jit_tls || !domain)
185 * The current LMF address is kept in a separate TLS variable, and its hard to read its value without
186 * arch-specific code. But the address of the TLS variable is stored in another TLS variable which
187 * can be accessed through MonoThreadInfo.
189 /* mono_set_lmf_addr () sets this */
190 addr = mono_thread_info_tls_get (info, TLS_KEY_LMF_ADDR);
194 tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = domain;
195 tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = jit_tls;
196 tctx->unwind_data [MONO_UNWIND_DATA_LMF] = lmf;