Ejemplo n.º 1
0
gboolean
mono_threads_wait_pending_operations (void)
{
	int i;
	int c = pending_suspends;

	/* Wait threads to park */
	THREADS_SUSPEND_DEBUG ("[INITIATOR-WAIT-COUNT] %d\n", c);
	if (pending_suspends) {
		MonoStopwatch suspension_time;
		mono_stopwatch_start (&suspension_time);
		for (i = 0; i < pending_suspends; ++i) {
			THREADS_SUSPEND_DEBUG ("[INITIATOR-WAIT-WAITING]\n");
			InterlockedIncrement (&waits_done);
			if (!mono_os_sem_timedwait (&suspend_semaphore, SLEEP_DURATION_BEFORE_ABORT, MONO_SEM_FLAGS_NONE))
				continue;
			mono_stopwatch_stop (&suspension_time);

			dump_threads ();

			MOSTLY_ASYNC_SAFE_PRINTF ("WAITING for %d threads, got %d suspended\n", (int)pending_suspends, i);
			g_error ("suspend_thread suspend took %d ms, which is more than the allowed %d ms", (int)mono_stopwatch_elapsed_ms (&suspension_time), SLEEP_DURATION_BEFORE_ABORT);
		}
		mono_stopwatch_stop (&suspension_time);
		THREADS_SUSPEND_DEBUG ("Suspending %d threads took %d ms.\n", (int)pending_suspends, (int)mono_stopwatch_elapsed_ms (&suspension_time));

	}

	pending_suspends = 0;

	return c > 0;
}
Ejemplo n.º 2
0
MONO_SIG_HANDLER_FUNC (static, sigterm_signal_handler)
{
	MONO_SIG_HANDLER_GET_CONTEXT;

	// Note: this function only returns for a single thread
	// When it's invoked on other threads once the dump begins,
	// those threads perform their dumps and then sleep until we
	// die. The dump ends with the exit(1) below
	MonoContext mctx;
	gchar *output = NULL;
	mono_sigctx_to_monoctx (ctx, &mctx);
	if (!mono_threads_summarize (&mctx, &output, NULL))
		g_assert_not_reached ();

	// Only the dumping-supervisor thread exits mono_thread_summarize
	MOSTLY_ASYNC_SAFE_PRINTF("Unhandled exception dump: \n######\n%s\n######\n", output);

	mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
	exit (1);
}
Ejemplo n.º 3
0
static void
dump_threads (void)
{
	MonoThreadInfo *info;
	MonoThreadInfo *cur = mono_thread_info_current ();

	MOSTLY_ASYNC_SAFE_PRINTF ("STATE CUE CARD: (? means a positive number, usually 1 or 2, * means any number)\n");
	MOSTLY_ASYNC_SAFE_PRINTF ("\t0x0\t- starting (GOOD, unless the thread is running managed code)\n");
	MOSTLY_ASYNC_SAFE_PRINTF ("\t0x1\t- running (BAD, unless it's the gc thread)\n");
	MOSTLY_ASYNC_SAFE_PRINTF ("\t0x2\t- detached (GOOD, unless the thread is running managed code)\n");
	MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?03\t- async suspended (GOOD)\n");
	MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?04\t- self suspended (GOOD)\n");
	MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?05\t- async suspend requested (BAD)\n");
	MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?06\t- self suspend requested (BAD)\n");
	MOSTLY_ASYNC_SAFE_PRINTF ("\t0x*07\t- blocking (GOOD)\n");
	MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?08\t- blocking with pending suspend (GOOD)\n");

	FOREACH_THREAD_SAFE (info) {
#ifdef TARGET_MACH
		char thread_name [256] = { 0 };
		pthread_getname_np (mono_thread_info_get_tid (info), thread_name, 255);

		MOSTLY_ASYNC_SAFE_PRINTF ("--thread %p id %p [%p] (%s) state %x  %s\n", info, (void *) mono_thread_info_get_tid (info), (void*)(size_t)info->native_handle, thread_name, info->thread_state, info == cur ? "GC INITIATOR" : "" );
#else
		MOSTLY_ASYNC_SAFE_PRINTF ("--thread %p id %p [%p] state %x  %s\n", info, (void *) mono_thread_info_get_tid (info), (void*)(size_t)info->native_handle, info->thread_state, info == cur ? "GC INITIATOR" : "" );
#endif

	} END_FOREACH_THREAD_SAFE
}