Пример #1
0
void
mono_error_cleanup (MonoError *oerror)
{
	// This function is called a lot so it is optimized.

	MonoErrorInternal *error = (MonoErrorInternal*)oerror;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
	const guint32 init = oerror->init;
	const guint16 error_code = (guint16)(init & 0xFFFF);
	const guint16 error_flags = (guint16)(init >> 16);
#else
	const guint16 error_code = error->error_code;
	const guint16 error_flags = error->flags;
#endif
	/* Two cleanups in a row without an intervening init. */
	g_assert (error_code != MONO_ERROR_CLEANUP_CALLED_SENTINEL);

	/* Mempool stored error shouldn't be cleaned up */
	g_assert (!is_boxed_error_flags (error_flags));

	/* Mark it as cleaned up. */
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
	oerror->init = MONO_ERROR_CLEANUP_CALLED_SENTINEL;
#else
	error->error_code = MONO_ERROR_CLEANUP_CALLED_SENTINEL;
	error->flags = 0;
#endif
	if (error_code == MONO_ERROR_NONE)
		return;

	if (is_managed_error_code (error_code))
		mono_gchandle_free_internal (error->exn.instance_handle);

	mono_error_free_string (&error->full_message);
	mono_error_free_string (&error->full_message_with_fields);

	if (!(error_flags & MONO_ERROR_FREE_STRINGS)) //no memory was allocated
		return;

	mono_error_free_string (&error->type_name);
	mono_error_free_string (&error->assembly_name);
	mono_error_free_string (&error->member_name);
	mono_error_free_string (&error->exception_name_space);
	mono_error_free_string (&error->exception_name);
	mono_error_free_string (&error->first_argument);
	error->exn.klass = NULL;
}
Пример #2
0
char *
mono_exception_handle_get_native_backtrace (MonoExceptionHandle exc)
{
#ifdef HAVE_BACKTRACE_SYMBOLS
	MonoDomain *domain;
	MonoArrayHandle arr = MONO_HANDLE_NEW(MonoArray, NULL);
	int i, len;
	GString *text;
	char **messages;

	MONO_HANDLE_GET (arr, exc, native_trace_ips);

	if (MONO_HANDLE_IS_NULL(arr))
		return g_strdup ("");
	domain = mono_domain_get ();
	len = mono_array_handle_length (arr);
	text = g_string_new_len (NULL, len * 20);
	uint32_t gchandle;
	gpointer *addr = MONO_ARRAY_HANDLE_PIN (arr, gpointer, 0, &gchandle);
	MONO_ENTER_GC_SAFE;
	messages = backtrace_symbols (addr, len);
	MONO_EXIT_GC_SAFE;
	mono_gchandle_free_internal (gchandle);

	for (i = 0; i < len; ++i) {
		gpointer ip;
		MONO_HANDLE_ARRAY_GETVAL (ip, arr, gpointer, i);
		MonoJitInfo *ji = mono_jit_info_table_find (domain, ip);
		if (ji) {
			char *msg = mono_debug_print_stack_frame (mono_jit_info_get_method (ji), (char*)ip - (char*)ji->code_start, domain);
			g_string_append_printf (text, "%s\n", msg);
			g_free (msg);
		} else {
			g_string_append_printf (text, "%s\n", messages [i]);
		}
	}

	g_free (messages);
	return g_string_free (text, FALSE);
#else
	return g_strdup ("");
#endif
}