Пример #1
0
SIG_HANDLER_FUNC (static, sigabrt_signal_handler)
{
	MonoJitInfo *ji = NULL;
	GET_CONTEXT;

	if (mono_thread_internal_current ())
		ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context(ctx));
	if (!ji) {
        if (mono_chain_signal (SIG_HANDLER_PARAMS))
			return;
		mono_handle_native_sigsegv (SIGABRT, ctx);
	}
}
Пример #2
0
MONO_SIG_HANDLER_FUNC (static, sigabrt_signal_handler)
{
	MonoJitInfo *ji = NULL;
	MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO ();
	MONO_SIG_HANDLER_GET_CONTEXT;

	if (mono_thread_internal_current ())
		ji = mono_jit_info_table_find_internal (mono_domain_get (), mono_arch_ip_from_context (ctx), TRUE, TRUE);
	if (!ji) {
        if (mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
			return;
		mono_handle_native_crash ("SIGABRT", ctx, info);
	}
}
Пример #3
0
MONO_SIG_HANDLER_FUNC (static, profiler_signal_handler)
{
	int old_errno = errno;

	MONO_SIG_HANDLER_GET_CONTEXT;

	/* See the comment in mono_runtime_shutdown_stat_profiler (). */
	if (mono_native_thread_id_get () == sampling_thread) {
		mono_atomic_inc_i32 (&profiler_interrupt_signals_received);
		return;
	}

	mono_atomic_inc_i32 (&profiler_signals_received);

	// Did a non-attached or detaching thread get the signal?
	if (mono_thread_info_get_small_id () == -1 ||
	    !mono_domain_get () ||
	    !mono_tls_get_jit_tls ()) {
		errno = old_errno;
		return;
	}

	// See the comment in sampling_thread_func ().
	mono_atomic_store_i32 (&mono_thread_info_current ()->profiler_signal_ack, 1);

	mono_atomic_inc_i32 (&profiler_signals_accepted);

	int hp_save_index = mono_hazard_pointer_save_for_signal_handler ();

	mono_thread_info_set_is_async_context (TRUE);

	MONO_PROFILER_RAISE (sample_hit, (mono_arch_ip_from_context (ctx), ctx));

	mono_thread_info_set_is_async_context (FALSE);

	mono_hazard_pointer_restore_for_signal_handler (hp_save_index);

	errno = old_errno;

	mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
}
Пример #4
0
void
mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *siginfo, gpointer fault_addr, gboolean stack_ovf)
{
#ifdef MONO_CROSS_COMPILE
	g_assert_not_reached ();
#else
#ifdef MONO_ARCH_USE_SIGACTION
	os_ucontext *uc = (ucontext_t*)sigctx;
	os_ucontext *uc_copy;
	MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (sigctx), NULL);
	gpointer *sp;
	int frame_size;

	if (stack_ovf) {
		const char *method;
		/* we don't do much now, but we can warn the user with a useful message */
		fprintf (stderr, "Stack overflow: IP: %p, SP: %p\n", mono_arch_ip_from_context (sigctx), (gpointer)UCONTEXT_REG_Rn(uc, 1));
		if (ji && !ji->is_trampoline && jinfo_get_method (ji))
			method = mono_method_full_name (jinfo_get_method (ji), TRUE);
		else
			method = "Unmanaged";
		fprintf (stderr, "At %s\n", method);
		abort ();
	}
	if (!ji)
		mono_handle_native_crash ("SIGSEGV", sigctx, siginfo);
	/* setup a call frame on the real stack so that control is returned there
	 * and exception handling can continue.
	 * The frame looks like:
	 *   ucontext struct
	 *   ...
	 * 224 is the size of the red zone
	 */
	frame_size = sizeof (ucontext_t) + sizeof (gpointer) * 16 + 224;
	frame_size += 15;
	frame_size &= ~15;
	sp = (gpointer)(UCONTEXT_REG_Rn(uc, 1) & ~15);
	sp = (gpointer)((char*)sp - frame_size);
	/* may need to adjust pointers in the new struct copy, depending on the OS */
	uc_copy = (ucontext_t*)(sp + 16);
	memcpy (uc_copy, uc, sizeof (os_ucontext));
#if defined(__linux__) && !defined(__mono_ppc64__)
	uc_copy->uc_mcontext.uc_regs = (gpointer)((char*)uc_copy + ((char*)uc->uc_mcontext.uc_regs - (char*)uc));
#endif
	g_assert (mono_arch_ip_from_context (uc) == mono_arch_ip_from_context (uc_copy));
	/* at the return form the signal handler execution starts in altstack_handle_and_restore() */
	UCONTEXT_REG_LNK(uc) = UCONTEXT_REG_NIP(uc);
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
	{
		MonoPPCFunctionDescriptor *handler_ftnptr = (MonoPPCFunctionDescriptor*)altstack_handle_and_restore;

		UCONTEXT_REG_NIP(uc) = (gulong)handler_ftnptr->code;
		UCONTEXT_REG_Rn(uc, 2) = (gulong)handler_ftnptr->toc;
	}
#else
	UCONTEXT_REG_NIP(uc) = (unsigned long)altstack_handle_and_restore;
#if _CALL_ELF == 2
	/* ELF v2 ABI calling convention requires to put the target address into
	* r12 if we use the global entry point of a function. */
	UCONTEXT_REG_Rn(uc, 12) = (unsigned long) altstack_handle_and_restore;
#endif
#endif
	UCONTEXT_REG_Rn(uc, 1) = (unsigned long)sp;
	UCONTEXT_REG_Rn(uc, PPC_FIRST_ARG_REG) = (unsigned long)(sp + 16);
	UCONTEXT_REG_Rn(uc, PPC_FIRST_ARG_REG + 1) = 0;
	UCONTEXT_REG_Rn(uc, PPC_FIRST_ARG_REG + 2) = 0;
#endif

#endif /* !MONO_CROSS_COMPILE */
}
Пример #5
0
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) {
		mono_profiler_stat_hit (mono_arch_ip_from_context (ctx), ctx);
	} else {
		MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
		int current_frame_index = 1;
		MonoContext mono_context;
		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);
			
			while ((current_frame_index <= call_chain_depth) &&
					(stack_bottom IS_BEFORE_ON_STACK (guchar*) current_frame) &&
					((guchar*) current_frame IS_BEFORE_ON_STACK stack_top)) {
				ips [current_frame_index] = CURRENT_FRAME_GET_RETURN_ADDRESS (current_frame);
				current_frame_index ++;
				stack_top = current_frame;
				current_frame = CURRENT_FRAME_GET_BASE_POINTER (current_frame);
			}
#else
				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);
					}
				}
			}
		}
		
		mono_profiler_stat_call_chain (current_frame_index, & ips [0], ctx);
	}

	mono_chain_signal (SIG_HANDLER_PARAMS);
}
Пример #6
0
static void
SIG_HANDLER_SIGNATURE (sigusr1_signal_handler)
{
	gboolean running_managed;
	MonoException *exc;
	MonoInternalThread *thread = mono_thread_internal_current ();
	MonoDomain *domain = mono_domain_get ();
	void *ji;
	
	GET_CONTEXT;

	if (!thread || !domain)
		/* The thread might not have started up yet */
		/* FIXME: Specify the synchronization with start_wrapper () in threads.c */
		return;

	if (thread->thread_dump_requested) {
		thread->thread_dump_requested = FALSE;

		mono_print_thread_dump (ctx);
	}

	/*
	 * This is an async signal, so the code below must not call anything which
	 * is not async safe. That includes the pthread locking functions. If we
	 * know that we interrupted managed code, then locking is safe.
	 */
	/*
	 * On OpenBSD, ctx can be NULL if we are interrupting poll ().
	 */
	if (ctx) {
		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;
	} else {
		running_managed = FALSE;
	}

	/* We can't do handler block checking from metadata since it requires doing
	 * a stack walk with context.
	 *
	 * FIXME add full-aot support.
	 */
#ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
	if (!mono_aot_only && ctx) {
		MonoThreadUnwindState unwind_state;
		if (mono_thread_state_init_from_sigctx (&unwind_state, ctx)) {
			if (mono_install_handler_block_guard (&unwind_state)) {
#ifndef HOST_WIN32
				/*Clear current thread from been wapi interrupted otherwise things can go south*/
				wapi_clear_interruption ();
#endif
				return;
			}
		}
	}
#endif

	exc = mono_thread_request_interruption (running_managed); 
	if (!exc)
		return;

	mono_arch_handle_exception (ctx, exc, FALSE);
}