diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index c840e1b7ae261..e5fd65378515a 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -5512,7 +5512,9 @@ decode_value_compute_size (MonoType *t, int type, MonoDomain *domain, guint8 *bu !(t->type == MONO_TYPE_PTR && type == MONO_TYPE_I8) && !(t->type == MONO_TYPE_FNPTR && type == MONO_TYPE_I8) && !(t->type == MONO_TYPE_GENERICINST && type == MONO_TYPE_VALUETYPE) && - !(t->type == MONO_TYPE_VALUETYPE && type == MONO_TYPE_OBJECT)) { + !(t->type == MONO_TYPE_VALUETYPE && type == MONO_TYPE_OBJECT) && + !(t->type == MONO_TYPE_VALUETYPE && type == MONO_TYPE_SZARRAY) && + !(t->type == MONO_TYPE_VALUETYPE && type == MONO_TYPE_ARRAY)) { char *name = mono_type_full_name (t); PRINT_DEBUG_MSG (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer) (gsize) mono_native_thread_id_get (), name, type); g_free (name); @@ -5580,7 +5582,7 @@ decode_value_compute_size (MonoType *t, int type, MonoDomain *domain, guint8 *bu handle_ref: default: if (MONO_TYPE_IS_REFERENCE (t)) { - if (type == MONO_TYPE_CLASS || type == MONO_TYPE_OBJECT || type == MONO_TYPE_STRING) { + if (type == MONO_TYPE_CLASS || type == MONO_TYPE_OBJECT || type == MONO_TYPE_STRING || type == MONO_TYPE_ARRAY || type == MONO_TYPE_SZARRAY) { ret += sizeof(MonoObject*); decode_objid (buf, &buf, limit); } else if (type == VALUE_TYPE_ID_NULL) { @@ -5635,7 +5637,9 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, !(t->type == MONO_TYPE_PTR && type == MONO_TYPE_I8) && !(t->type == MONO_TYPE_FNPTR && type == MONO_TYPE_I8) && !(t->type == MONO_TYPE_GENERICINST && type == MONO_TYPE_VALUETYPE) && - !(t->type == MONO_TYPE_VALUETYPE && type == MONO_TYPE_OBJECT)) { + !(t->type == MONO_TYPE_VALUETYPE && type == MONO_TYPE_OBJECT) && + !(t->type == MONO_TYPE_VALUETYPE && type == MONO_TYPE_SZARRAY) && + !(t->type == MONO_TYPE_VALUETYPE && type == MONO_TYPE_ARRAY)) { char *name = mono_type_full_name (t); PRINT_DEBUG_MSG (1, "[%p] Expected value of type %s, got 0x%0x.\n", (gpointer) (gsize) mono_native_thread_id_get (), name, type); g_free (name); @@ -5728,7 +5732,7 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, handle_ref: default: if (MONO_TYPE_IS_REFERENCE (t)) { - if (type == MONO_TYPE_CLASS || type == MONO_TYPE_OBJECT || type == MONO_TYPE_STRING) { + if (type == MONO_TYPE_CLASS || type == MONO_TYPE_OBJECT || type == MONO_TYPE_STRING || type == MONO_TYPE_ARRAY || type == MONO_TYPE_SZARRAY) { int objid = decode_objid (buf, &buf, limit); MonoObject *obj; diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index 82282501cfedf..844ed5b4d5419 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -564,16 +564,29 @@ private void Write(T1 type, T2 value) where T1 : struct where T2 : struc public void WriteObj(DotnetObjectId objectId, MonoSDBHelper SdbHelper) { - if (objectId.Scheme == "object") + switch (objectId.Scheme) { - Write(ElementType.Class, objectId.Value); - } - else if (objectId.Scheme == "valuetype") - { - if (SdbHelper.ValueCreator.TryGetValueTypeById(objectId.Value, out ValueTypeClass vt)) + case "object": + { + Write(ElementType.Class, objectId.Value); + break; + } + case "array": + { + Write(ElementType.Array, objectId.Value); + break; + } + case "valuetype": + { + if (!SdbHelper.ValueCreator.TryGetValueTypeById(objectId.Value, out ValueTypeClass vt)) + throw new ArgumentException($"Could not find any valuetype with id: {objectId.Value}", nameof(objectId.Value)); Write(vt.Buffer); - else - throw new ArgumentException($"Could not find any valuetype with id: {objectId.Value}", nameof(objectId.Value)); + break; + } + default: + { + throw new NotImplementedException($"Writing object of scheme: {objectId.Scheme} is not supported"); + } } } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index fac84a7df124c..60ed3fdd4c288 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -585,7 +585,7 @@ public async Task EvaluateIndexingNegative() => await CheckInspectLocalsAtBreakp Assert.Equal("Unable to evaluate element access 'f.idx0[2]': Cannot apply indexing with [] to a primitive object of type 'number'", res.Error["result"]?["description"]?.Value()); var exceptionDetailsStack = res.Error["exceptionDetails"]?["stackTrace"]?["callFrames"]?[0]; Assert.Equal("DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", exceptionDetailsStack?["functionName"]?.Value()); - Assert.Equal(559, exceptionDetailsStack?["lineNumber"]?.Value()); + Assert.Equal(560, exceptionDetailsStack?["lineNumber"]?.Value()); Assert.Equal(12, exceptionDetailsStack?["columnNumber"]?.Value()); (_, res) = await EvaluateOnCallFrame(id, "f[1]", expect_ok: false ); Assert.Equal( "Unable to evaluate element access 'f[1]': Cannot apply indexing with [] to an object of type 'DebuggerTests.EvaluateLocalsWithIndexingTests.TestEvaluate'", res.Error["result"]?["description"]?.Value()); @@ -650,7 +650,7 @@ await EvaluateOnCallFrameAndCheck(id, [Fact] public async Task EvaluateObjectByNonIntLocals() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 13, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 14, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", wait_for_event_fn: async (pause_location) => { @@ -663,6 +663,7 @@ await EvaluateOnCallFrameAndCheck(id, ("f[aFloat]", TNumber(1)), ("f[aDouble]", TNumber(2)), ("f[aDecimal]", TNumber(3)), + ("f[arr]", TChar('t')), ("f[objIdx]", TNumber(123)) ); }); @@ -723,7 +724,7 @@ public async Task EvaluateIndexingByExpressionNegative() => await CheckInspectLo Assert.Equal("Unable to evaluate element access 'f.numList[\"a\" + 1]': Cannot index with an object of type 'string'", res.Error["result"]?["description"]?.Value()); var exceptionDetailsStack = res.Error["exceptionDetails"]?["stackTrace"]?["callFrames"]?[0]; Assert.Equal("DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", exceptionDetailsStack?["functionName"]?.Value()); - Assert.Equal(559, exceptionDetailsStack?["lineNumber"]?.Value()); + Assert.Equal(560, exceptionDetailsStack?["lineNumber"]?.Value()); Assert.Equal(12, exceptionDetailsStack?["columnNumber"]?.Value()); }); diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs index 05a0e349c0ef5..cd4fdc2003899 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs @@ -532,6 +532,7 @@ public class TestEvaluate public int this[float key] => (int)key; public int this[decimal key] => (int)key; public int this[Indexer indexer] => indexer.index; + public char this[char[] arr] => arr.Length == 0 ? '0' : arr[0]; public void run() { @@ -565,6 +566,7 @@ public static void EvaluateLocals() double aDouble = 2.34; decimal aDecimal = 3.34m; Indexer objIdx = new(index: 123); + char[] arr = new char[] { 't', 'e', 's', 't' }; } }