Skip to content

Commit

Permalink
Add mono_exception_try_get_managed_backtrace(). (dotnet#38391)
Browse files Browse the repository at this point in the history
This is an enhanced version of `mono_exception_get_managed_backtrace()` that takes an optional `const char *prefix` argument (to indent the stack-trace) and returns FALSE with a NULL backtrace on error.

Co-authored-by: baulig <[email protected]>
  • Loading branch information
monojenkins and baulig authored Jun 29, 2020
1 parent 7d9ec59 commit ff5447d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 9 deletions.
41 changes: 32 additions & 9 deletions src/mono/mono/metadata/exception.c
Original file line number Diff line number Diff line change
Expand Up @@ -1114,35 +1114,58 @@ mono_get_exception_runtime_wrapped_handle (MonoObjectHandle wrapped_exception, M
HANDLE_FUNCTION_RETURN_REF (MonoException, MONO_HANDLE_CAST (MonoException, o));
}

typedef struct {
GString *text;
const char *prefix;
} AppendFrameData;

static gboolean
append_frame_and_continue (MonoMethod *method, gpointer ip, size_t native_offset, gboolean managed, gpointer user_data)
{
MONO_ENTER_GC_UNSAFE;
MonoDomain *domain = mono_domain_get ();
GString *text = (GString*)user_data;
AppendFrameData *data = (AppendFrameData *)user_data;

if (data->prefix)
g_string_append (data->text, data->prefix);
if (method) {
char *msg = mono_debug_print_stack_frame (method, native_offset, domain);
g_string_append_printf (text, "%s\n", msg);
g_string_append_printf (data->text, "%s\n", msg);
g_free (msg);
} else {
g_string_append_printf (text, "<unknown native frame 0x%p>\n", ip);
g_string_append_printf (data->text, "at <unknown native frame 0x%p>\n", ip);
}
MONO_EXIT_GC_UNSAFE;
return FALSE;
}

gboolean
mono_exception_try_get_managed_backtrace (MonoException *exc, const char *prefix, char **result)
{
AppendFrameData data;

data.text = g_string_new_len (NULL, 20);
data.prefix = prefix;

if (!mono_get_eh_callbacks ()->mono_exception_walk_trace (exc, append_frame_and_continue, &data)) {
g_string_free (data.text, TRUE);
*result = NULL;
return FALSE;
}

*result = g_string_free (data.text, FALSE);
return TRUE;
}

char *
mono_exception_get_managed_backtrace (MonoException *exc)
{
GString *text;

text = g_string_new_len (NULL, 20);
char *result;

if (!mono_get_eh_callbacks ()->mono_exception_walk_trace (exc, append_frame_and_continue, text))
g_string_append (text, "managed backtrace not available\n");
if (!mono_exception_try_get_managed_backtrace (exc, NULL, &result))
return g_strdup ("managed backtrace not available\n");

return g_string_free (text, FALSE);
return result;
}

char *
Expand Down
3 changes: 3 additions & 0 deletions src/mono/mono/metadata/object-internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -2051,6 +2051,9 @@ mono_exception_handle_get_native_backtrace (MonoExceptionHandle exc);
char *
mono_exception_get_managed_backtrace (MonoException *exc);

gboolean
mono_exception_try_get_managed_backtrace (MonoException *exc, const char *prefix, char **result);

void
mono_copy_value (MonoType *type, void *dest, void *value, int deref_pointer);

Expand Down

0 comments on commit ff5447d

Please sign in to comment.