#include <ctype.h>
#include "trace.h"
#include "version.h"
+#include "debugger-agent.h"
#include "jit-icalls.h"
{
gboolean running_managed;
MonoException *exc;
- MonoThread *thread = mono_thread_current ();
+ MonoInternalThread *thread = mono_thread_internal_current ();
MonoDomain *domain = mono_domain_get ();
void *ji;
*/
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)
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) {
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);
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);
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);
return (pid_t) syscall (SYS_fork);
#else
g_assert_not_reached ();
+ return;
#endif
}