[runtime] Read fields out of TransparentProxies correctly in debugger agent
authorAlexander Kyte <alexmkyte@fastmail.com>
Mon, 4 Jan 2016 18:34:23 +0000 (13:34 -0500)
committerAlexander Kyte <alexmkyte@fastmail.com>
Tue, 5 Jan 2016 18:56:46 +0000 (13:56 -0500)
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mono/mini/debugger-agent.c

index 7b99f7b7e32ed594e92f9cb7da7abbaff676dc13..150738e6633c1a6e9473953105245bb0872e069f 100644 (file)
@@ -1200,6 +1200,8 @@ public class Tests : TestsBase, ITest2
                CrossDomain o = (CrossDomain)domain.CreateInstanceAndUnwrap (
                                   typeof (CrossDomain).Assembly.FullName, "CrossDomain");
 
+               domains_print_across (o);
+
                domains_2 (o, new CrossDomain ());
 
                o.invoke_2 ();
@@ -1223,6 +1225,10 @@ public class Tests : TestsBase, ITest2
        public static void domains_2 (object o, object o2) {
        }
 
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void domains_print_across (object o) {
+       }
+
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
        public static void domains_3 () {
        }
@@ -1454,8 +1460,13 @@ class TypeLoadClass {
 class TypeLoadClass2 {
 }
 
+public class SentinelClass : MarshalByRefObject {
+}
+
 public class CrossDomain : MarshalByRefObject
 {
+       SentinelClass printMe = new SentinelClass ();
+
        public void invoke () {
                Tests.invoke_in_domain ();
        }
index ff7b3616df855d53c0acc30c6f22b5e68b5e112c..c54baffecf94c174e38e13a24b9b26f32ded1c05 100644 (file)
@@ -2937,6 +2937,22 @@ public class DebuggerTests
                ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
        }
 
+       [Test]
+       public void MemberInOtherDomain () {
+               vm.Detach ();
+
+               Start (new string [] { "dtest-app.exe", "domain-test" });
+
+               vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
+
+               Event e = run_until ("domains_print_across");
+
+               var frame = e.Thread.GetFrames ()[0];
+               var inOtherDomain = frame.GetArgument (0) as ObjectMirror;
+               var crossDomainField = (ObjectMirror) inOtherDomain.GetValue (inOtherDomain.Type.GetField("printMe"));
+               Assert.AreEqual ("SentinelClass", crossDomainField.Type.Name);
+       }
+
        [Test]
        public void Domains () {
                vm.Detach ();
index a8e6b3920eb370ed43e229f6f4ce9d1317dffe39..40aa4828c44ac900e828142255762c01066f0b94 100644 (file)
@@ -9198,10 +9198,13 @@ object_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                return err;
 
        MonoClass *obj_type;
+       gboolean remote_obj = FALSE;
 
        obj_type = obj->vtable->klass;
-       if (mono_class_is_transparent_proxy (obj_type))
+       if (mono_class_is_transparent_proxy (obj_type)) {
                obj_type = ((MonoTransparentProxy *)obj)->remote_class->proxy_class;
+               remote_obj = TRUE;
+       }
 
        g_assert (obj_type);
 
@@ -9243,7 +9246,15 @@ object_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                                buffer_add_value (buf, f->type, val, obj->vtable->domain);
                                g_free (val);
                        } else {
-                               buffer_add_value (buf, f->type, (guint8*)obj + f->offset, obj->vtable->domain);
+                               guint8 *field_value = NULL;
+                               void *field_storage = NULL;
+
+                               if (remote_obj) {
+                                       field_value = mono_load_remote_field(obj, obj_type, f, &field_storage);
+                               } else
+                                       field_value = (guint8*)obj + f->offset;
+
+                               buffer_add_value (buf, f->type, field_value, obj->vtable->domain);
                        }
                }
                break;