From 7b01f49b04fb5cb1e5b4be89be1690a5cbcf2e43 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Tue, 8 Sep 2020 19:23:00 -0400 Subject: [PATCH 1/2] [wasm][debugger] Avoid infinite loop when we have a boxed `new object` Eg. `object o = new object(); object o1 = o;` - Avoid infinitely looping for `o1` --- src/mono/mono/mini/mini-wasm-debugger.c | 4 +++ .../wasm/debugger/DebuggerTestSuite/Tests.cs | 26 +++++++++++++++++++ src/mono/wasm/debugger/tests/debugger-test.cs | 26 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/mono/mono/mini/mini-wasm-debugger.c b/src/mono/mono/mini/mini-wasm-debugger.c index b978d60051b575..82a48a32606f2b 100644 --- a/src/mono/mono/mini/mini-wasm-debugger.c +++ b/src/mono/mono/mini/mini-wasm-debugger.c @@ -928,6 +928,10 @@ describe_value(MonoType * type, gpointer addr, int gpflags) } type = m_class_get_byval_arg (klass); + if (type->type == MONO_TYPE_OBJECT) { + mono_wasm_add_obj_var ("object", "object", get_object_id (obj)); + break; + } // Boxed valuetype if (m_class_is_valuetype (klass)) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs index ad3fae97d500c4..47b4f5ea3cecc8 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs @@ -1061,6 +1061,32 @@ await CheckProps(o_ia_props, new[] }, nameof(o_ia_props)); }); + [Theory] + [InlineData("BoxedTypeObjectTest", false)] + [InlineData("BoxedTypeObjectTestAsync", true)] + public async Task InspectBoxedTypeObject(string method_name, bool is_async) => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTest", + method_name, + 9, + is_async ? "MoveNext" : method_name, + $"window.setTimeout(function() {{ invoke_static_method_async('[debugger-test] DebuggerTest:{method_name}'); }}, 1);", + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var dt = new DateTime(2310, 1, 2, 3, 4, 5); + await CheckProps(locals, new + { + i = TNumber(5), + o0 = TNumber(5), + o1 = TNumber(5), + o2 = TNumber(5), + o3 = TNumber(5), + + oo = TObject("object"), + oo0 = TObject("object"), + }, "locals"); + }); + [Theory] [InlineData(false)] [InlineData(true)] diff --git a/src/mono/wasm/debugger/tests/debugger-test.cs b/src/mono/wasm/debugger/tests/debugger-test.cs index 7de05543c7619e..576db670ac2b4b 100644 --- a/src/mono/wasm/debugger/tests/debugger-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test.cs @@ -382,6 +382,32 @@ public static async Task BoxingTestAsync() Console.WriteLine ($"break here"); await Task.CompletedTask; } + + public static void BoxedTypeObjectTest() + { + int i = 5; + object o0 = i; + object o1 = o0; + object o2 = o1; + object o3 = o2; + + object oo = new object(); + object oo0 = oo; + Console.WriteLine ($"break here"); + } + public static async Task BoxedTypeObjectTestAsync() + { + int i = 5; + object o0 = i; + object o1 = o0; + object o2 = o1; + object o3 = o2; + + object oo = new object(); + object oo0 = oo; + Console.WriteLine ($"break here"); + await Task.CompletedTask; + } } public class MulticastDelegateTestClass From 35f70e04c74879ca5112d528f15eaa7dcaf427a2 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 10 Sep 2020 18:14:07 -0400 Subject: [PATCH 2/2] [wasm][debugger] Handle valuetypes boxed in classes that are not .. type `object`. Prompted by @lambdageek's comment - https://github.com/dotnet/runtime/pull/42059#issuecomment-690310274 --- src/mono/mono/mini/mini-wasm-debugger.c | 6 +++++ .../wasm/debugger/DebuggerTestSuite/Tests.cs | 25 +++++++++++++++++++ src/mono/wasm/debugger/tests/debugger-test.cs | 21 ++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/src/mono/mono/mini/mini-wasm-debugger.c b/src/mono/mono/mini/mini-wasm-debugger.c index 82a48a32606f2b..c4f8031f959711 100644 --- a/src/mono/mono/mini/mini-wasm-debugger.c +++ b/src/mono/mono/mini/mini-wasm-debugger.c @@ -969,6 +969,12 @@ describe_value(MonoType * type, gpointer addr, int gpflags) MonoObject *obj = *(MonoObject**)addr; MonoClass *klass = type->data.klass; + if (m_class_is_valuetype (mono_object_class (obj))) { + addr = mono_object_unbox_internal (obj); + type = m_class_get_byval_arg (mono_object_class (obj)); + goto handle_vtype; + } + char *class_name = mono_type_full_name (type); int obj_id = get_object_id (obj); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs index 47b4f5ea3cecc8..16296b6f033d1d 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs @@ -1087,6 +1087,31 @@ public async Task InspectBoxedTypeObject(string method_name, bool is_async) => a }, "locals"); }); + [Theory] + [InlineData("BoxedAsClass", false)] + [InlineData("BoxedAsClassAsync", true)] + public async Task InspectBoxedAsClassLocals(string method_name, bool is_async) => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTest", + method_name, + 6, + is_async ? "MoveNext" : method_name, + $"window.setTimeout(function() {{ invoke_static_method_async('[debugger-test] DebuggerTest:{method_name}'); }}, 1);", + wait_for_event_fn: async (pause_location) => + { + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + var dt = new DateTime(2310, 1, 2, 3, 4, 5); + Console.WriteLine (locals); + + await CheckProps(locals, new + { + vt_dt = TDateTime(new DateTime(4819, 5, 6, 7, 8, 9)), + vt_gs = TValueType("Math.GenericStruct"), + e = TEnum("System.IO.FileMode", "0"), + ee = TEnum("System.IO.FileMode", "Append") + }, "locals"); + }); + + [Theory] [InlineData(false)] [InlineData(true)] diff --git a/src/mono/wasm/debugger/tests/debugger-test.cs b/src/mono/wasm/debugger/tests/debugger-test.cs index 576db670ac2b4b..ceb550001694b3 100644 --- a/src/mono/wasm/debugger/tests/debugger-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test.cs @@ -408,6 +408,27 @@ public static async Task BoxedTypeObjectTestAsync() Console.WriteLine ($"break here"); await Task.CompletedTask; } + + public static void BoxedAsClass() + { + ValueType vt_dt = new DateTime(4819, 5, 6, 7, 8, 9); + ValueType vt_gs = new Math.GenericStruct { StringField = "vt_gs#StringField" }; + Enum e = new System.IO.FileMode(); + Enum ee = System.IO.FileMode.Append; + + Console.WriteLine ($"break here"); + } + + public static async Task BoxedAsClassAsync() + { + ValueType vt_dt = new DateTime(4819, 5, 6, 7, 8, 9); + ValueType vt_gs = new Math.GenericStruct { StringField = "vt_gs#StringField" }; + Enum e = new System.IO.FileMode(); + Enum ee = System.IO.FileMode.Append; + + Console.WriteLine ($"break here"); + await Task.CompletedTask; + } } public class MulticastDelegateTestClass