[sdb][interp] Use the interpreter's resume state to compute the IL offset in compute_...
authorimhameed <50922266+imhameed@users.noreply.github.com>
Thu, 8 Aug 2019 00:05:55 +0000 (17:05 -0700)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Thu, 8 Aug 2019 00:05:55 +0000 (20:05 -0400)
[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
src/mono/mono/mini/ee.h
src/mono/mono/mini/interp-stubs.c
src/mono/mono/mini/interp/interp.c

index b556b69..c9c0b5e 100644 (file)
@@ -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);
+                       }
+               }
+       }
 }
 
 /*
index 1c2595b..d686ce7 100644 (file)
@@ -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)) \
index 78cc3ce..bc6ad72 100644 (file)
@@ -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)
 {
index 284b800..f32eb47 100644 (file)
@@ -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:
  *