removing PLATFORM_WIN32
[mono.git] / mono / mini / mini-posix.c
index 9059e91007272554dc25601b8ac7c332df5e2eeb..cb4952cf75918e74dabc0dad0b5067364c64d3d9 100644 (file)
@@ -59,6 +59,7 @@
 #include <ctype.h>
 #include "trace.h"
 #include "version.h"
+#include "debugger-agent.h"
 
 #include "jit-icalls.h"
 
@@ -159,7 +160,7 @@ SIG_HANDLER_SIGNATURE (sigusr1_signal_handler)
 {
        gboolean running_managed;
        MonoException *exc;
-       MonoThread *thread = mono_thread_current ();
+       MonoInternalThread *thread = mono_thread_internal_current ();
        MonoDomain *domain = mono_domain_get ();
        void *ji;
        
@@ -184,6 +185,9 @@ SIG_HANDLER_SIGNATURE (sigusr1_signal_handler)
         */
        ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context(ctx));
        running_managed = ji != NULL;
+
+       if (mono_debugger_agent_thread_interrupt (ctx, ji))
+               return;
        
        exc = mono_thread_request_interruption (running_managed); 
        if (!exc)
@@ -224,6 +228,7 @@ static void
 SIG_HANDLER_SIGNATURE (sigprof_signal_handler)
 {
        int call_chain_depth = mono_profiler_stat_get_call_chain_depth ();
+       MonoProfilerCallChainStrategy call_chain_strategy = mono_profiler_stat_get_call_chain_strategy ();
        GET_CONTEXT;
        
        if (call_chain_depth == 0) {
@@ -232,20 +237,18 @@ SIG_HANDLER_SIGNATURE (sigprof_signal_handler)
                MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
                int current_frame_index = 1;
                MonoContext mono_context;
-#if FULL_STAT_PROFILER_BACKTRACE
-               guchar *current_frame;
-               guchar *stack_bottom;
-               guchar *stack_top;
-#else
-               MonoDomain *domain;
-#endif
                guchar *ips [call_chain_depth + 1];
 
                mono_arch_sigctx_to_monoctx (ctx, &mono_context);
                ips [0] = MONO_CONTEXT_GET_IP (&mono_context);
                
                if (jit_tls != NULL) {
+                       if (call_chain_strategy == MONO_PROFILER_CALL_CHAIN_NATIVE) {
 #if FULL_STAT_PROFILER_BACKTRACE
+                       guchar *current_frame;
+                       guchar *stack_bottom;
+                       guchar *stack_top;
+                       
                        stack_bottom = jit_tls->end_of_stack;
                        stack_top = MONO_CONTEXT_GET_SP (&mono_context);
                        current_frame = MONO_CONTEXT_GET_BP (&mono_context);
@@ -259,24 +262,37 @@ SIG_HANDLER_SIGNATURE (sigprof_signal_handler)
                                current_frame = CURRENT_FRAME_GET_BASE_POINTER (current_frame);
                        }
 #else
-                       domain = mono_domain_get ();
-                       if (domain != NULL) {
-                               MonoLMF *lmf = NULL;
-                               MonoJitInfo *ji;
-                               MonoJitInfo res;
-                               MonoContext new_mono_context;
-                               int native_offset;
-                               ji = mono_find_jit_info (domain, jit_tls, &res, NULL, &mono_context,
-                                               &new_mono_context, NULL, &lmf, &native_offset, NULL);
-                               while ((ji != NULL) && (current_frame_index <= call_chain_depth)) {
-                                       ips [current_frame_index] = MONO_CONTEXT_GET_IP (&new_mono_context);
-                                       current_frame_index ++;
-                                       mono_context = new_mono_context;
+                               call_chain_strategy = MONO_PROFILER_CALL_CHAIN_GLIBC;
+#endif
+                       }
+                       
+                       if (call_chain_strategy == MONO_PROFILER_CALL_CHAIN_GLIBC) {
+#if GLIBC_PROFILER_BACKTRACE
+                               current_frame_index = backtrace ((void**) & ips [1], call_chain_depth);
+#else
+                               call_chain_strategy = MONO_PROFILER_CALL_CHAIN_MANAGED;
+#endif
+                       }
+
+                       if (call_chain_strategy == MONO_PROFILER_CALL_CHAIN_MANAGED) {
+                               MonoDomain *domain = mono_domain_get ();
+                               if (domain != NULL) {
+                                       MonoLMF *lmf = NULL;
+                                       MonoJitInfo *ji;
+                                       MonoJitInfo res;
+                                       MonoContext new_mono_context;
+                                       int native_offset;
                                        ji = mono_find_jit_info (domain, jit_tls, &res, NULL, &mono_context,
                                                        &new_mono_context, NULL, &lmf, &native_offset, NULL);
+                                       while ((ji != NULL) && (current_frame_index <= call_chain_depth)) {
+                                               ips [current_frame_index] = MONO_CONTEXT_GET_IP (&new_mono_context);
+                                               current_frame_index ++;
+                                               mono_context = new_mono_context;
+                                               ji = mono_find_jit_info (domain, jit_tls, &res, NULL, &mono_context,
+                                                               &new_mono_context, NULL, &lmf, &native_offset, NULL);
+                                       }
                                }
                        }
-#endif
                }
                
                mono_profiler_stat_call_chain (current_frame_index, & ips [0], ctx);
@@ -335,9 +351,27 @@ add_signal_handler (int signo, gpointer handler)
        sigemptyset (&sa.sa_mask);
        sa.sa_flags = SA_SIGINFO;
 #ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
-       if (signo == SIGSEGV)
+       if (signo == SIGSEGV) {
                sa.sa_flags |= SA_ONSTACK;
+
+               /* 
+                * libgc will crash when trying to do stack marking for threads which are on
+                * an altstack, so delay the suspend signal after the signal handler has
+                * executed.
+                */
+               if (mono_gc_get_suspend_signal () != -1)
+                       sigaddset (&sa.sa_mask, mono_gc_get_suspend_signal ());
+       }
 #endif
+       if (signo == SIGSEGV) {
+               /* 
+                * Delay abort signals while handling SIGSEGVs since they could go unnoticed.
+                */
+               sigset_t block_mask;
+     
+               sigemptyset (&block_mask);
+               sigaddset (&sa.sa_mask, mono_thread_get_abort_signal ());
+       }
 #else
        sa.sa_handler = handler;
        sigemptyset (&sa.sa_mask);
@@ -534,6 +568,7 @@ mono_runtime_syscall_fork ()
        return (pid_t) syscall (SYS_fork);
 #else
        g_assert_not_reached ();
+       return;
 #endif
 }