Skip to content

Commit

Permalink
Add API to get more data from a managed exception's stack trace.
Browse files Browse the repository at this point in the history
This is used by crash reporting to report the stack trace of the exception
when the exception was thrown (for unhandled exceptions), instead of the
stack trace when the unhandled exception hook is called (which may be
different because finally clauses may have executed altering the intial
stack state).
  • Loading branch information
rolfbjarne committed Jan 3, 2013
1 parent 061edfc commit 1cf5599
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
41 changes: 41 additions & 0 deletions mono/mini/mini-exceptions.c
Expand Up @@ -499,6 +499,47 @@ get_method_from_stack_frame (MonoJitInfo *ji, gpointer generic_info)
return method;
}

/**
* mono_exception_walk_native_trace:
* @ex: The exception object whose frames should be walked
* @func: callback to call for each stack frame
* @user_data: data passed to the callback
*
* This function walks the stacktrace of an exception. For
* each frame the callback function is called with the relevant info.
* The walk ends when no more stack frames are found or when the callback
* returns a TRUE value.
*/

gboolean
mono_exception_walk_trace (MonoException *ex, MonoExceptionFrameWalk func, gpointer user_data)
{
MonoDomain *domain = mono_domain_get ();
MonoArray *ta = ex->trace_ips;
int len, i;

if (ta == NULL)
return FALSE;

len = mono_array_length (ta) >> 1;
for (i = 0; i < len; i++) {
gpointer ip = mono_array_get (ta, gpointer, i * 2 + 0);
gpointer generic_info = mono_array_get (ta, gpointer, i * 2 + 1);
MonoJitInfo *ji = mono_jit_info_table_find (domain, ip);

if (ji == NULL) {
if (func (NULL, ip, 0, FALSE, user_data))
return TRUE;
} else {
MonoMethod *method = get_method_from_stack_frame (ji, generic_info);
if (func (method, ji->code_start, (char *) ip - (char *) ji->code_start, TRUE, user_data))
return TRUE;
}
}

return len > 0;
}

MonoString *
ves_icall_System_Exception_get_trace (MonoException *ex)
{
Expand Down
3 changes: 3 additions & 0 deletions mono/mini/mini.h
Expand Up @@ -2150,6 +2150,9 @@ void mono_resume_unwind (MonoContext *ctx) MONO_LLVM_INT

MonoJitInfo * mono_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, MonoJitInfo *res, MonoJitInfo *prev_ji, MonoContext *ctx, MonoContext *new_ctx, char **trace, MonoLMF **lmf, int *native_offset, gboolean *managed) MONO_INTERNAL;

typedef gboolean (*MonoExceptionFrameWalk) (MonoMethod *method, gpointer ip, size_t native_offset, gboolean managed, gpointer user_data);
gboolean mono_exception_walk_trace (MonoException *ex, MonoExceptionFrameWalk func, gpointer user_data);

gboolean
mono_find_jit_info_ext (MonoDomain *domain, MonoJitTlsData *jit_tls,
MonoJitInfo *prev_ji, MonoContext *ctx,
Expand Down

0 comments on commit 1cf5599

Please sign in to comment.