From c567a1efe95f23c9d2a11019e95f36697ca539de Mon Sep 17 00:00:00 2001 From: imhameed <50922266+imhameed@users.noreply.github.com> Date: Wed, 7 Aug 2019 17:05:55 -0700 Subject: [PATCH] [sdb][interp] Use the interpreter's resume state to compute the IL offset in compute_frame_info. (mono/mono#15936) [sdb][interp] Use the interpreter's resume state to compute the IL offset in compute_frame_info. This recovers the relevant bits of the "resume state" from the interpreter and uses that to recalculate the `il_offset` for the top frame. Fixes https://github.com/mono/mono/issues/15687. Commit migrated from https://github.com/mono/mono/commit/fc4d234ef61bc3150be6a3d15e8e80a6bc9fbfa5 --- src/mono/mono/mini/debugger-agent.c | 39 +++++++++++++++++++++++++++++-------- src/mono/mono/mini/ee.h | 3 ++- src/mono/mono/mini/interp-stubs.c | 6 ++++++ src/mono/mono/mini/interp/interp.c | 13 +++++++++++++ 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index b556b69..c9c0b5e 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -3109,6 +3109,21 @@ no_seq_points_found (MonoMethod *method, int offset) printf ("Unable to find seq points for method '%s', offset 0x%x.\n", mono_method_full_name (method, TRUE), offset); } +static int +calc_il_offset (MonoDomain *domain, MonoMethod *method, int native_offset, gboolean is_top_frame) +{ + int ret = -1; + if (is_top_frame) { + SeqPoint sp; + /* mono_debug_il_offset_from_address () doesn't seem to be precise enough (#2092) */ + if (mono_find_prev_seq_point_for_native_offset (domain, method, native_offset, NULL, &sp)) + ret = sp.il_offset; + } + if (ret == -1) + ret = mono_debug_il_offset_from_address (method, domain, native_offset); + return ret; +} + typedef struct { DebuggerTlsData *tls; GSList *frames; @@ -3121,7 +3136,6 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data) ComputeFramesUserData *ud = (ComputeFramesUserData *)user_data; StackFrame *frame; MonoMethod *method, *actual_method, *api_method; - SeqPoint sp; int flags = 0; mono_loader_lock (); @@ -3155,13 +3169,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data) } if (info->il_offset == -1) { - /* mono_debug_il_offset_from_address () doesn't seem to be precise enough (#2092) */ - if (ud->frames == NULL) { - if (mono_find_prev_seq_point_for_native_offset (info->domain, method, info->native_offset, NULL, &sp)) - info->il_offset = sp.il_offset; - } - if (info->il_offset == -1) - info->il_offset = mono_debug_il_offset_from_address (method, info->domain, info->native_offset); + info->il_offset = calc_il_offset (info->domain, method, info->native_offset, ud->frames == NULL); } DEBUG_PRINTF (1, "\tFrame: %s:[il=0x%x, native=0x%x] %d\n", mono_method_full_name (method, TRUE), info->il_offset, info->native_offset, info->managed); @@ -3386,6 +3394,21 @@ compute_frame_info (MonoInternalThread *thread, DebuggerTlsData *tls, gboolean f tls->frames = new_frames; tls->frame_count = new_frame_count; tls->frames_up_to_date = TRUE; + + if (CHECK_PROTOCOL_VERSION (2, 52)) { + MonoJitTlsData *jit_data = thread->thread_info->jit_data; + gboolean has_interp_resume_state = FALSE; + MonoInterpFrameHandle interp_resume_frame = NULL; + gpointer interp_resume_ip = 0; + mini_get_interp_callbacks ()->get_resume_state (jit_data, &has_interp_resume_state, &interp_resume_frame, &interp_resume_ip); + if (has_interp_resume_state && tls->frame_count > 0) { + StackFrame *top_frame = tls->frames [0]; + if (interp_resume_frame == top_frame->interp_frame) { + int native_offset = (int) ((uintptr_t) interp_resume_ip - (uintptr_t) top_frame->de.ji->code_start); + top_frame->il_offset = calc_il_offset (top_frame->de.domain, top_frame->de.method, native_offset, TRUE); + } + } + } } /* diff --git a/src/mono/mono/mini/ee.h b/src/mono/mono/mini/ee.h index 1c2595b..d686ce7 100644 --- a/src/mono/mono/mini/ee.h +++ b/src/mono/mono/mini/ee.h @@ -15,7 +15,7 @@ #ifndef __MONO_EE_H__ #define __MONO_EE_H__ -#define MONO_EE_API_VERSION 0xc +#define MONO_EE_API_VERSION 0xd typedef struct _MonoInterpStackIter MonoInterpStackIter; @@ -36,6 +36,7 @@ typedef gpointer MonoInterpFrameHandle; MONO_EE_CALLBACK (void, delegate_ctor, (MonoObjectHandle this_obj, MonoObjectHandle target, gpointer addr, MonoError *error)) \ MONO_EE_CALLBACK (gpointer, get_remoting_invoke, (MonoMethod *method, gpointer imethod, MonoError *error)) \ MONO_EE_CALLBACK (void, set_resume_state, (MonoJitTlsData *jit_tls, MonoException *ex, MonoJitExceptionInfo *ei, MonoInterpFrameHandle interp_frame, gpointer handler_ip)) \ + MONO_EE_CALLBACK (void, get_resume_state, (const MonoJitTlsData *jit_tls, gboolean *has_resume_state, MonoInterpFrameHandle *interp_frame, gpointer *handler_ip)) \ MONO_EE_CALLBACK (gboolean, run_finally, (StackFrameInfo *frame, int clause_index, gpointer handler_ip, gpointer handler_ip_end)) \ MONO_EE_CALLBACK (gboolean, run_filter, (StackFrameInfo *frame, MonoException *ex, int clause_index, gpointer handler_ip, gpointer handler_ip_end)) \ MONO_EE_CALLBACK (void, frame_iter_init, (MonoInterpStackIter *iter, gpointer interp_exit_data)) \ diff --git a/src/mono/mono/mini/interp-stubs.c b/src/mono/mono/mini/interp-stubs.c index 78cc3ce..bc6ad72 100644 --- a/src/mono/mono/mini/interp-stubs.c +++ b/src/mono/mono/mini/interp-stubs.c @@ -87,6 +87,12 @@ stub_set_resume_state (MonoJitTlsData *jit_tls, MonoException *ex, MonoJitExcept g_assert_not_reached (); } +static void +stub_get_resume_state (const MonoJitTlsData *jit_tls, gboolean *has_resume_state, MonoInterpFrameHandle *interp_frame, gpointer *handler_ip) +{ + has_resume_state = FALSE; +} + static gboolean stub_run_finally (StackFrameInfo *frame, int clause_index, gpointer handler_ip, gpointer handler_ip_end) { diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 284b800..f32eb47 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -6519,6 +6519,19 @@ interp_set_resume_state (MonoJitTlsData *jit_tls, MonoException *ex, MonoJitExce context->handler_ip = (guint16*) handler_ip; } +static void +interp_get_resume_state (const MonoJitTlsData *jit_tls, gboolean *has_resume_state, MonoInterpFrameHandle *interp_frame, gpointer *handler_ip) +{ + g_assert (jit_tls); + ThreadContext *context = (ThreadContext*)jit_tls->interp_context; + g_assert (context); + *has_resume_state = context->has_resume_state; + if (context->has_resume_state) { + *interp_frame = context->handler_frame; + *handler_ip = context->handler_ip; + } +} + /* * interp_run_finally: * -- 2.7.4