Fix gshared support in the soft debugger. Fixes #651251.
authorZoltan Varga <vargaz@gmail.com>
Fri, 5 Nov 2010 04:20:19 +0000 (05:20 +0100)
committerZoltan Varga <vargaz@gmail.com>
Fri, 5 Nov 2010 04:20:54 +0000 (05:20 +0100)
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mono/mini/debugger-agent.c
mono/mini/mini-exceptions.c
mono/mini/mini.h

index 758f2d3291f9786fdadd5dfe7c362fef67e8e0b8..50b5dc475adf71ec6bfd084a049d917c1feae08d 100644 (file)
@@ -409,7 +409,7 @@ public class Tests : TestsBase
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
        public static void locals () {
                locals1 (null);
-               locals2 (null, 5);
+               locals2<string> (null, 5, "ABC");
                locals3 ();
        }
 
@@ -423,13 +423,15 @@ public class Tests : TestsBase
        }
 
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
-       public static void locals2 (string[] args, int arg) {
+       public static void locals2<T> (string[] args, int arg, T t) {
                long i = 42;
                string s = "AB";
 
                for (int j = 0; j < 10; ++j) {
                        if (s != null)
                                i ++;
+                       if (t != null)
+                               i ++;
                }
        }
 
index 6d9049af6f7c5115602552fe855d340caa6eadc1..c0b0d87ff161e2a6ce957e6699ab539976359832 100644 (file)
@@ -94,7 +94,7 @@ public class DebuggerTests
                }
 
                Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
-               Assert.AreEqual (m, (e as BreakpointEvent).Method);
+               Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
 
                return (e as BreakpointEvent);
        }
@@ -886,7 +886,6 @@ public class DebuggerTests
        }
 
        [Test]
-       [Category ("only")]
        public void Type_SetValue () {
                var e = run_until ("o1");
                var frame = e.Thread.GetFrames () [0];
@@ -1320,8 +1319,8 @@ public class DebuggerTests
                StackFrame frame = e.Thread.GetFrames () [0];
 
                var locals = frame.Method.GetLocals ();
-               Assert.AreEqual (5, locals.Length);
-               for (int i = 0; i < 5; ++i) {
+               Assert.AreEqual (6, locals.Length);
+               for (int i = 0; i < 6; ++i) {
                        if (locals [i].Name == "args") {
                                Assert.IsTrue (locals [i].IsArg);
                                Assert.AreEqual ("String[]", locals [i].Type.Name);
@@ -1337,6 +1336,10 @@ public class DebuggerTests
                        } else if (locals [i].Name == "s") {
                                Assert.IsFalse (locals [i].IsArg);
                                Assert.AreEqual ("String", locals [i].Type.Name);
+                       } else if (locals [i].Name == "t") {
+                               // gshared
+                               Assert.IsTrue (locals [i].IsArg);
+                               Assert.AreEqual ("String", locals [i].Type.Name);
                        } else {
                                Assert.Fail ();
                        }
@@ -1344,6 +1347,7 @@ public class DebuggerTests
        }
 
        [Test]
+       [Category ("only")]
        public void Locals () {
                var be = run_until ("locals1");
 
@@ -1386,6 +1390,8 @@ public class DebuggerTests
                                AssertValue (42, vals [i]);
                        if (locals [i].Name == "s")
                                AssertValue ("AB", vals [i]);
+                       if (locals [i].Name == "t")
+                               AssertValue ("ABC", vals [i]);
                }
 
                // Argument checking
@@ -1668,7 +1674,6 @@ public class DebuggerTests
        }
 
        [Test]
-       [Category ("only")]
        public void CreateBoxedValue () {
                ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
 
@@ -2000,6 +2005,7 @@ public class DebuggerTests
        }
 
        [Test]
+       [Category ("only")]
        public void Frame_SetValue () {
                Event e = run_until ("locals2");
 
@@ -2025,6 +2031,11 @@ public class DebuggerTests
                frame.SetValue (p, vm.CreateValue (7));
                AssertValue (7, frame.GetValue (p));
 
+               // gshared
+               p = frame.Method.GetParameters ()[2];
+               frame.SetValue (p, vm.RootDomain.CreateString ("DEF"));
+               AssertValue ("DEF", frame.GetValue (p));
+
                // argument checking
 
                // variable null
index 9ad729484b33aa8f8d5cde66783721780f91cf54..611353e50147ee7e32d632975914368b487904db 100644 (file)
@@ -112,6 +112,11 @@ typedef struct
        guint32 il_offset;
        MonoDomain *domain;
        MonoMethod *method;
+       /*
+        * If method is gshared, this is the actual instance, otherwise this is equal to
+        * method.
+        */
+       MonoMethod *actual_method;
        MonoContext ctx;
        MonoDebugMethodJitInfo *jit;
        int flags;
@@ -2444,7 +2449,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
 {
        ComputeFramesUserData *ud = user_data;
        StackFrame *frame;
-       MonoMethod *method;
+       MonoMethod *method, *actual_method;
 
        if (info->type != FRAME_TYPE_MANAGED) {
                if (info->type == FRAME_TYPE_DEBUGGER_INVOKE) {
@@ -2459,6 +2464,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
                method = info->ji->method;
        else
                method = info->method;
+       actual_method = info->actual_method;
 
        if (!method || (method->wrapper_type && method->wrapper_type != MONO_WRAPPER_DYNAMIC_METHOD))
                return FALSE;
@@ -2482,6 +2488,7 @@ process_frame (StackFrameInfo *info, MonoContext *ctx, gpointer user_data)
 
        frame = g_new0 (StackFrame, 1);
        frame->method = method;
+       frame->actual_method = actual_method;
        frame->il_offset = info->il_offset;
        if (ctx) {
                frame->ctx = *ctx;
@@ -6258,7 +6265,7 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                buffer_add_int (buf, tls->frame_count);
                for (i = 0; i < tls->frame_count; ++i) {
                        buffer_add_int (buf, tls->frames [i]->id);
-                       buffer_add_methodid (buf, tls->frames [i]->domain, tls->frames [i]->method);
+                       buffer_add_methodid (buf, tls->frames [i]->domain, tls->frames [i]->actual_method);
                        buffer_add_int (buf, tls->frames [i]->il_offset);
                        /*
                         * Instead of passing the frame type directly to the client, we associate
@@ -6338,7 +6345,7 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
        }
        jit = frame->jit;
 
-       sig = mono_method_signature (frame->method);
+       sig = mono_method_signature (frame->actual_method);
 
        switch (command) {
        case CMD_STACK_FRAME_GET_VALUES: {
index b975e580d5fcd6993d4b681828ba8c9fefeaba10..aeda21cac361cc2aa12795aeb287c82167b4636e 100644 (file)
@@ -737,6 +737,11 @@ mono_jit_walk_stack_from_ctx_in_thread (MonoJitStackWalk func, MonoDomain *domai
 
                frame.il_offset = il_offset;
 
+               if (frame.ji)
+                       frame.actual_method = get_method_from_stack_frame (frame.ji, get_generic_info_from_stack_frame (frame.ji, &ctx));
+               else
+                       frame.actual_method = frame.method;
+
                if (func (&frame, &ctx, user_data))
                        return;
                
index 204b47df4c600e08daf7eb4f0af99dfb21265c4a..fd211e046595ea3ed54e48ba778175e075730309 100644 (file)
@@ -230,6 +230,10 @@ typedef struct {
         * to native code, or the method which was JITted.
         */
        MonoMethod *method;
+       /*
+        * If ji->method is a gshared method, this is the actual method instance.
+        */
+       MonoMethod *actual_method;
        /* The domain containing the code executed by this frame */
        MonoDomain *domain;
        gboolean managed;