From 4bd84ac5de965eeca746ebdfa7f400eae10f217c Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Wed, 5 May 2021 14:29:45 +0200 Subject: [PATCH 1/4] - fix null reference in describe_value() + add test for it - fix null reference in PDB load - improved handling of targetCrashed in Inspector - improve Makefile to allow passing test arguments together with filters - add windows chrome to probe path - include debugging payload into test failure exception for easier debugging - make it possible to compile with WasmBuildNative=true - make it possible to compile with Debug runtime - enable Mono logging in debug mode --- src/mono/mono/mini/mini-wasm-debugger.c | 14 +- src/mono/wasm/build/WasmApp.InTree.targets | 2 +- src/mono/wasm/build/WasmApp.targets | 3 +- .../DebuggerTestSuite/AssignmentTests.cs | 235 ++++++++++++++++++ .../DebuggerTestSuite/DebuggerTestBase.cs | 48 ++-- .../debugger/DebuggerTestSuite/Inspector.cs | 13 +- .../wasm/debugger/tests/Directory.Build.props | 7 +- .../debugger-test/debugger-stepping-test.cs | 232 +++++++++++++++++ .../tests/debugger-test/debugger-test.csproj | 4 +- 9 files changed, 530 insertions(+), 28 deletions(-) create mode 100644 src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs create mode 100644 src/mono/wasm/debugger/tests/debugger-test/debugger-stepping-test.cs diff --git a/src/mono/mono/mini/mini-wasm-debugger.c b/src/mono/mono/mini/mini-wasm-debugger.c index 52a79089ad590e..352bb81deb9232 100644 --- a/src/mono/mono/mini/mini-wasm-debugger.c +++ b/src/mono/mono/mini/mini-wasm-debugger.c @@ -541,7 +541,7 @@ assembly_loaded (MonoProfiler *prof, MonoAssembly *assembly) MonoDebugHandle *handle = mono_debug_get_handle (assembly_image); if (handle) { MonoPPDBFile *ppdb = handle->ppdb; - if (!mono_ppdb_is_embedded (ppdb)) { //if it's an embedded pdb we don't need to send pdb extrated to DebuggerProxy. + if (ppdb && !mono_ppdb_is_embedded (ppdb)) { //if it's an embedded pdb we don't need to send pdb extrated to DebuggerProxy. pdb_image = mono_ppdb_get_image (ppdb); mono_wasm_asm_loaded (assembly_image->assembly_name, assembly_image->raw_data, assembly_image->raw_data_len, pdb_image->raw_data, pdb_image->raw_data_len); return; @@ -1023,6 +1023,10 @@ describe_value(MonoType * type, gpointer addr, int gpflags) case MONO_TYPE_OBJECT: { MonoObject *obj = *(MonoObject**)addr; + if (!obj) { + mono_wasm_add_obj_var ("object", NULL, 0); + break; + } MonoClass *klass = obj->vtable->klass; if (!klass) { // boxed null @@ -1070,6 +1074,12 @@ describe_value(MonoType * type, gpointer addr, int gpflags) case MONO_TYPE_ARRAY: case MONO_TYPE_CLASS: { MonoObject *obj = *(MonoObject**)addr; + if (!obj) { + char *class_name = mono_type_full_name (type); + mono_wasm_add_func_var (class_name, NULL, 0); + g_free (class_name); + return TRUE; + } MonoClass *klass = type->data.klass; if (m_class_is_valuetype (mono_object_class (obj))) { @@ -1523,7 +1533,7 @@ describe_variable (InterpFrame *frame, MonoMethod *method, MonoMethodHeader *hea addr = mini_get_interp_callbacks ()->frame_get_local (frame, pos); } - PRINT_DEBUG_MSG (2, "adding val %p type [%p] %s\n", addr, type, mono_type_full_name (type)); + PRINT_DEBUG_MSG (2, "adding val %p type 0x%x %s\n", addr, type->type, mono_type_full_name (type)); return describe_value(type, addr, gpflags); } diff --git a/src/mono/wasm/build/WasmApp.InTree.targets b/src/mono/wasm/build/WasmApp.InTree.targets index cde8075f0874c5..f92f2abd62bc6d 100644 --- a/src/mono/wasm/build/WasmApp.InTree.targets +++ b/src/mono/wasm/build/WasmApp.InTree.targets @@ -25,7 +25,7 @@ + Targets="Build"/> + @@ -221,7 +222,7 @@ $([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidDir))) $([MSBuild]::NormalizeDirectory($(MicrosoftNetCoreAppRuntimePackRidDir), 'native')) - $([MSBuild]::NormalizePath($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'cross', $(PackageRID), 'mono-aot-cross$(_ExeExt)')) + $([MSBuild]::NormalizePath($(MicrosoftNetCoreAppRuntimePackRidNativeDir), 'cross', $(RuntimeIdentifier), 'mono-aot-cross$(_ExeExt)')) <_WasmIntermediateOutputPath>$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'wasm')) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs new file mode 100644 index 00000000000000..25432dbbe46498 --- /dev/null +++ b/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs @@ -0,0 +1,235 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Linq; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using Xunit; + +namespace DebuggerTests +{ + public class AssignmentTests : DebuggerTestBase + { + [Fact] + async Task InspectObjectAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_OBJECT", + (locals) => CheckObject(locals, "r", "object", is_null: true), + (locals) => CheckObject(locals, "r", "object") + ); + } + + [Fact] + async Task InspectClassAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_CLASS", + (locals) => CheckObject(locals, "r", "DebuggerTests.MONO_TYPE_CLASS", is_null: true), + (locals) => CheckObject(locals, "r", "DebuggerTests.MONO_TYPE_CLASS") + ); + } + + [Fact] + async Task InspectBoolAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_BOOLEAN", + (locals) => CheckBool(locals, "r", default), + (locals) => CheckBool(locals, "r", true) + ); + } + + [Fact] + async Task InspectCharAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_CHAR", + (locals) => CheckSymbol(locals, "r", "0 '\u0000'"), + (locals) => CheckSymbol(locals, "r", "97 'a'") + ); + } + + [Fact] + async Task InspectSByteAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_I1", + (locals) => CheckNumber(locals, "r", default), + (locals) => CheckNumber(locals, "r", -1) + ); + } + + [Fact] + async Task InspectShortAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_I2", + (locals) => CheckNumber(locals, "r", default), + (locals) => CheckNumber(locals, "r", -1) + ); + } + + [Fact] + async Task InspectIntAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_I4", + (locals) => CheckNumber(locals, "r", default), + (locals) => CheckNumber(locals, "r", -1) + ); + } + + [Fact] + async Task InspectLongAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_I8", + (locals) => CheckNumber(locals, "r", default), + (locals) => CheckNumber(locals, "r", -1) + ); + } + + [Fact] + async Task InspectByteAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_U1", + (locals) => CheckNumber(locals, "r", default), + (locals) => CheckNumber(locals, "r", 1) + ); + } + + [Fact] + async Task InspectUShortAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_U2", + (locals) => CheckNumber(locals, "r", default), + (locals) => CheckNumber(locals, "r", 1) + ); + } + + [Fact] + async Task InspectUIntAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_U4", + (locals) => CheckNumber(locals, "r", default), + (locals) => CheckNumber(locals, "r", 1) + ); + } + + [Fact] + async Task InspectULongAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_U8", + (locals) => CheckNumber(locals, "r", default), + (locals) => CheckNumber(locals, "r", 1) + ); + } + + [Fact] + async Task InspectFloatAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_R4", + (locals) => CheckNumber(locals, "r", default), + (locals) => CheckNumber(locals, "r", 3.1415F) + ); + } + + [Fact] + async Task InspectDoubleAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_R8", + (locals) => CheckNumber(locals, "r", default), + (locals) => CheckNumber(locals, "r", 3.1415D) + ); + } + + [Fact] + async Task InspectStringAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_STRING", + (locals) => CheckString(locals, "r", default), + (locals) => CheckString(locals, "r", "hello") + ); + } + + [Fact] + async Task InspectEnumAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_ENUM", + (locals) => CheckEnum(locals, "r", "DebuggerTests.RGB", "Red"), + (locals) => CheckEnum(locals, "r", "DebuggerTests.RGB", "Blue") + ); + } + + [Fact] + async Task InspectArrayAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_ARRAY", + (locals) => CheckObject(locals, "r", "byte[]", is_null: true), + (locals) => CheckArray(locals, "r", "byte[]", 2) + ); + } + + [Fact] + async Task InspectStructAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_VALUETYPE", + (locals) => CheckValueType(locals, "r", "DebuggerTests.Point"), + (locals) => CheckValueType(locals, "r", "DebuggerTests.Point") + ); + } + + [Fact] + async Task InspectDecimalAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_VALUETYPE2", + (locals) => CheckValueType(locals, "r", "System.Decimal", description: "0"), + (locals) => CheckValueType(locals, "r", "System.Decimal", description: "1.1") + ); + } + + [Fact] + async Task InspectFunctionAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_GENERICINST", + (locals) => CheckObject(locals, "r", "System.Func", is_null: true), + (locals) => CheckObject(locals, "r", "System.Func", description: "int OuterMethod ()") + ); + } + + [Fact] + async Task InspectFunctionPtrAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_FNPTR", + (locals) => CheckSymbol(locals, "r", "(*()) 0"), + (locals) => { } // CheckObject(locals, "r", "(*()) 0x22dd230") // FixMe: Could we do better ? + ); + } + + [Fact] + async Task InspectIntPtrAssignmentsDuringSteppingIn() + { + await InspectAssignmentDuringSteppingIn("MONO_TYPE_PTR", + (locals) => CheckSymbol(locals, "r", "(int*) 0"), + (locals) => { } //CheckObject(locals, "r", "(int*) 0x211c058") // FixMe: Could we do better ? + ); + } + + private async Task InspectAssignmentDuringSteppingIn(string clazz, Action checkDefault, Action checkValue) + { + await SetBreakpointInMethod("debugger-test", "DebuggerTests." + clazz, "OuterMethod", 2); + await EvaluateAndCheck("window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests." + clazz + ":OuterMethod'); })", null, -1, -1, "OuterMethod"); + + await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-stepping-test.cs", -1, -1, "InnerMethod", + locals_fn: (locals) => + { + Console.WriteLine(locals); + Assert.Equal(2, locals.Count()); + checkDefault(locals); + } + ); + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-stepping-test.cs", -1, -1, "InnerMethod", times: 3, + locals_fn: (locals) => + { + Console.WriteLine(locals); + Assert.Equal(2, locals.Count()); + checkValue(locals); + } + ); + } + } +} diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs index 826dc212d15259..a89c292d992a1e 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs @@ -53,6 +53,7 @@ static protected string FindTestPath() "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge", "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary", "/usr/bin/chromium", + "C:/Program Files/Google/Chrome/Application/chrome.exe", "/usr/bin/chromium-browser", }; static string chrome_path; @@ -85,19 +86,19 @@ public DebuggerTestBase(string driver = "debugger-driver.html") public virtual async Task InitializeAsync() { - Func)>> fn = (client, token) => - { - Func)> getInitCmdFn = (cmd) => (cmd, client.SendCommand(cmd, null, token)); - var init_cmds = new List<(string, Task)> - { + Func)>> fn = (client, token) => + { + Func)> getInitCmdFn = (cmd) => (cmd, client.SendCommand(cmd, null, token)); + var init_cmds = new List<(string, Task)> + { getInitCmdFn("Profiler.enable"), getInitCmdFn("Runtime.enable"), getInitCmdFn("Debugger.enable"), getInitCmdFn("Runtime.runIfWaitingForDebugger") - }; + }; - return init_cmds; - }; + return init_cmds; + }; await Ready(); await insp.OpenSessionAsync(fn); @@ -149,9 +150,9 @@ await EvaluateAndCheck( function_name, wait_for_event_fn: async (pause_location) => { - //make sure we're on the right bp + //make sure we're on the right bp - Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value()); + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value()); var top_frame = pause_location!["callFrames"]?[0]; @@ -258,11 +259,11 @@ internal JToken CheckSymbol(JToken locals, string name, string value) return l; } - internal JToken CheckObject(JToken locals, string name, string class_name, string subtype = null, bool is_null = false) + internal JToken CheckObject(JToken locals, string name, string class_name, string subtype = null, bool is_null = false, string description = null) { var l = GetAndAssertObjectWithName(locals, name); var val = l["value"]; - CheckValue(val, TObject(class_name, is_null: is_null), name).Wait(); + CheckValue(val, TObject(class_name, is_null: is_null, description: description), name).Wait(); Assert.True(val["isValueType"] == null || !val["isValueType"].Value()); return l; @@ -326,10 +327,10 @@ internal void CheckContentValue(JToken token, string value) Assert.Equal(value, val); } - internal JToken CheckValueType(JToken locals, string name, string class_name) + internal JToken CheckValueType(JToken locals, string name, string class_name, string description=null) { var l = GetAndAssertObjectWithName(locals, name); - CheckValue(l["value"], TValueType(class_name), name).Wait(); + CheckValue(l["value"], TValueType(class_name, description: description), name).Wait(); return l; } @@ -409,7 +410,7 @@ internal async Task InvokeGetter(JToken obj, object arguments, string fn { functionDeclaration = fn, objectId = obj["value"]?["objectId"]?.Value(), - arguments = new[] { new { value = property } , new { value = newvalue } }, + arguments = new[] { new { value = property }, new { value = newvalue } }, silent = true }); var res = await cli.SendCommand("Runtime.callFunctionOn", req, token); @@ -467,7 +468,14 @@ internal async Task SendCommandAndCheck(JObject args, string method, st if (locals_fn != null) { var locals = await GetProperties(wait_res["callFrames"][0]["callFrameId"].Value()); - locals_fn(locals); + try + { + locals_fn(locals); + } + catch (System.AggregateException ex) + { + throw new AggregateException(ex.Message + " \n" + locals.ToString(), ex); + } } return wait_res; @@ -697,9 +705,9 @@ internal async Task CheckValue(JToken actual_val, JToken exp_val, string label) AssertEqual(exp_val_str, actual_field_val_str, $"[{label}] Value for json property named {jp.Name} didn't match."); } } - catch + catch (Exception ex) { - Console.WriteLine($"Expected: {exp_val}. Actual: {actual_val}"); + Console.WriteLine($"{ex.Message} \nExpected: {exp_val} \nActual: {actual_val}"); throw; } } @@ -844,8 +852,8 @@ internal async Task RemoveBreakpoint(string id, bool expect_ok = true) internal async Task SetBreakpoint(string url_key, int line, int column, bool expect_ok = true, bool use_regex = false, string condition = "") { var bp1_req = !use_regex ? - JObject.FromObject(new { lineNumber = line, columnNumber = column, url = dicFileToUrl[url_key], condition}) : - JObject.FromObject(new { lineNumber = line, columnNumber = column, urlRegex = url_key, condition}); + JObject.FromObject(new { lineNumber = line, columnNumber = column, url = dicFileToUrl[url_key], condition }) : + JObject.FromObject(new { lineNumber = line, columnNumber = column, urlRegex = url_key, condition }); var bp1_res = await cli.SendCommand("Debugger.setBreakpointByUrl", bp1_req, token); Assert.True(expect_ok ? bp1_res.IsOk : bp1_res.IsErr); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs index c555cd0439767c..826d860c21e4d4 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Inspector.cs @@ -147,6 +147,7 @@ private static string FormatConsoleAPICalled(JObject args) async Task OnMessage(string method, JObject args, CancellationToken token) { + bool fail = false; switch (method) { case "Debugger.paused": @@ -158,14 +159,22 @@ async Task OnMessage(string method, JObject args, CancellationToken token) case "Runtime.consoleAPICalled": _logger.LogInformation(FormatConsoleAPICalled(args)); break; + case "Inspector.detached": + case "Inspector.targetCrashed": + case "Inspector.targetReloadedAfterCrash": + fail = true; + break; + case "Runtime.exceptionThrown": + _logger.LogDebug($"Failing all waiters because: {method}: {args}"); + fail = true; + break; } if (eventListeners.TryGetValue(method, out var listener)) { await listener(args, token).ConfigureAwait(false); } - else if (String.Compare(method, "Runtime.exceptionThrown") == 0) + else if (fail) { - _logger.LogDebug($"Failing all waiters because: {method}: {args}"); FailAllWaiters(new ArgumentException(args.ToString())); } } diff --git a/src/mono/wasm/debugger/tests/Directory.Build.props b/src/mono/wasm/debugger/tests/Directory.Build.props index 2506fb59a82143..3b6a8dd44b0b65 100644 --- a/src/mono/wasm/debugger/tests/Directory.Build.props +++ b/src/mono/wasm/debugger/tests/Directory.Build.props @@ -5,7 +5,7 @@ $(AspNetCoreAppCurrent) Library Debug - Release + Release true 219 @@ -16,4 +16,9 @@ $(ArtifactsBinDir)microsoft.netcore.app.runtime.browser-wasm\$(RuntimeConfiguration)\runtimes\browser-wasm\ + + + 5 + + diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-stepping-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-stepping-test.cs new file mode 100644 index 00000000000000..ba922908373c00 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-stepping-test.cs @@ -0,0 +1,232 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +namespace DebuggerTests +{ + public struct StepInTest + { + public static int InnerMethod(T value) + { + T r; + r = value; + return 0; + } + } + + public class MONO_TYPE_OBJECT + { + public static int OuterMethod() + { + var value = new object(); + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_CLASS + { + public static int OuterMethod() + { + var value = new MONO_TYPE_CLASS(); + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_BOOLEAN + { + public static int OuterMethod() + { + var value = true; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_CHAR + { + public static int OuterMethod() + { + var value = 'a'; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_I1 + { + public static int OuterMethod() + { + sbyte value = -1; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_I2 + { + public static int OuterMethod() + { + short value = -1; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_I4 + { + public static int OuterMethod() + { + int value = -1; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_I8 + { + public static int OuterMethod() + { + long value = -1; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_U1 + { + public static int OuterMethod() + { + byte value = 1; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_U2 + { + public static int OuterMethod() + { + ushort value = 1; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_U4 + { + public static int OuterMethod() + { + uint value = 1; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_U8 + { + public static int OuterMethod() + { + ulong value = 1; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_R4 + { + public static int OuterMethod() + { + float value = 3.1415F; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_R8 + { + public static int OuterMethod() + { + double value = 3.1415D; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_STRING + { + public static int OuterMethod() + { + string value = "hello"; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_ENUM + { + public static int OuterMethod() + { + RGB value = RGB.Blue; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_ARRAY + { + public static int OuterMethod() + { + byte[] value = new byte[2] { 1, 2 }; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_VALUETYPE + { + public static int OuterMethod() + { + Point value = new Point(); + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_VALUETYPE2 + { + public static int OuterMethod() + { + Decimal value = 1.1m; + return StepInTest.InnerMethod(value); + } + } + + public class MONO_TYPE_GENERICINST + { + public static int OuterMethod() + { + Func value = MONO_TYPE_GENERICINST.OuterMethod; + return StepInTest>.InnerMethod(value); + } + } + + public class MONO_TYPE_FNPTR + { + public unsafe static int OuterMethod() + { + delegate* value = &MONO_TYPE_FNPTR.OuterMethod; + return InnerMethod(value); + } + + public unsafe static int InnerMethod(delegate* value) + { + delegate* r; + r = value; + return 0; + } + } + + public class MONO_TYPE_PTR + { + public unsafe static int OuterMethod() + { + int a = 1; int* value = &a; + return InnerMethod(value); + } + + public unsafe static int InnerMethod(int* value) + { + int* r; + r = value; + return 0; + } + } +} diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj index 880220a06ffa3a..3e13d2154e3814 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj @@ -24,7 +24,7 @@ $(AppDir) $(MonoProjectRoot)wasm\runtime-test.js - 1 + 1 true @@ -36,6 +36,8 @@ + + From 9649dbf003453c4b724227e3f7cc6af7ebf75d3e Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Thu, 6 May 2021 13:22:01 +0200 Subject: [PATCH 2/4] code review feedback --- .../DebuggerTestSuite/AssignmentTests.cs | 13 ++- ...ng-test.cs => debugger-assignment-test.cs} | 102 +++++++++--------- 2 files changed, 60 insertions(+), 55 deletions(-) rename src/mono/wasm/debugger/tests/debugger-test/{debugger-stepping-test.cs => debugger-assignment-test.cs} (51%) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs index 25432dbbe46498..f40b986fe25f67 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs @@ -187,7 +187,7 @@ async Task InspectFunctionAssignmentsDuringSteppingIn() { await InspectAssignmentDuringSteppingIn("MONO_TYPE_GENERICINST", (locals) => CheckObject(locals, "r", "System.Func", is_null: true), - (locals) => CheckObject(locals, "r", "System.Func", description: "int OuterMethod ()") + (locals) => CheckObject(locals, "r", "System.Func", description: "int Prepare ()") ); } @@ -211,10 +211,11 @@ await InspectAssignmentDuringSteppingIn("MONO_TYPE_PTR", private async Task InspectAssignmentDuringSteppingIn(string clazz, Action checkDefault, Action checkValue) { - await SetBreakpointInMethod("debugger-test", "DebuggerTests." + clazz, "OuterMethod", 2); - await EvaluateAndCheck("window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests." + clazz + ":OuterMethod'); })", null, -1, -1, "OuterMethod"); + await SetBreakpointInMethod("debugger-test", "DebuggerTests." + clazz, "Prepare", 2); + await EvaluateAndCheck("window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests." + clazz + ":Prepare'); })", null, -1, -1, "Prepare"); - await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-stepping-test.cs", -1, -1, "InnerMethod", + // 1) check un-assigned variables + await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-assignment-test.cs", -1, -1, "TestedMethod", locals_fn: (locals) => { Console.WriteLine(locals); @@ -222,7 +223,9 @@ await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-stepping- checkDefault(locals); } ); - await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-stepping-test.cs", -1, -1, "InnerMethod", times: 3, + + // 2) check assigned variables + await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-assignment-test.cs", -1, -1, "TestedMethod", times: 3, locals_fn: (locals) => { Console.WriteLine(locals); diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-stepping-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-assignment-test.cs similarity index 51% rename from src/mono/wasm/debugger/tests/debugger-test/debugger-stepping-test.cs rename to src/mono/wasm/debugger/tests/debugger-test/debugger-assignment-test.cs index ba922908373c00..e316c2a658bf12 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-stepping-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-assignment-test.cs @@ -8,205 +8,207 @@ using System.Threading.Tasks; namespace DebuggerTests { - public struct StepInTest + public class StepInTest { - public static int InnerMethod(T value) + public static int TestedMethod(T value) { + // 1) break here and check un-assigned variables T r; r = value; + // 2) break here and check assigned variables return 0; } } public class MONO_TYPE_OBJECT { - public static int OuterMethod() + public static int Prepare() { var value = new object(); - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_CLASS { - public static int OuterMethod() + public static int Prepare() { var value = new MONO_TYPE_CLASS(); - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_BOOLEAN { - public static int OuterMethod() + public static int Prepare() { var value = true; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_CHAR { - public static int OuterMethod() + public static int Prepare() { var value = 'a'; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_I1 { - public static int OuterMethod() + public static int Prepare() { sbyte value = -1; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_I2 { - public static int OuterMethod() + public static int Prepare() { short value = -1; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_I4 { - public static int OuterMethod() + public static int Prepare() { int value = -1; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_I8 { - public static int OuterMethod() + public static int Prepare() { long value = -1; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_U1 { - public static int OuterMethod() + public static int Prepare() { byte value = 1; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_U2 { - public static int OuterMethod() + public static int Prepare() { ushort value = 1; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_U4 { - public static int OuterMethod() + public static int Prepare() { uint value = 1; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_U8 { - public static int OuterMethod() + public static int Prepare() { ulong value = 1; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_R4 { - public static int OuterMethod() + public static int Prepare() { float value = 3.1415F; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_R8 { - public static int OuterMethod() + public static int Prepare() { double value = 3.1415D; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_STRING { - public static int OuterMethod() + public static int Prepare() { string value = "hello"; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_ENUM { - public static int OuterMethod() + public static int Prepare() { RGB value = RGB.Blue; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_ARRAY { - public static int OuterMethod() + public static int Prepare() { byte[] value = new byte[2] { 1, 2 }; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_VALUETYPE { - public static int OuterMethod() + public static int Prepare() { Point value = new Point(); - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_VALUETYPE2 { - public static int OuterMethod() + public static int Prepare() { Decimal value = 1.1m; - return StepInTest.InnerMethod(value); + return StepInTest.TestedMethod(value); } } public class MONO_TYPE_GENERICINST { - public static int OuterMethod() + public static int Prepare() { - Func value = MONO_TYPE_GENERICINST.OuterMethod; - return StepInTest>.InnerMethod(value); + Func value = MONO_TYPE_GENERICINST.Prepare; + return StepInTest>.TestedMethod(value); } } public class MONO_TYPE_FNPTR { - public unsafe static int OuterMethod() + public unsafe static int Prepare() { - delegate* value = &MONO_TYPE_FNPTR.OuterMethod; - return InnerMethod(value); + delegate* value = &MONO_TYPE_FNPTR.Prepare; + return TestedMethod(value); } - public unsafe static int InnerMethod(delegate* value) + public unsafe static int TestedMethod(delegate* value) { delegate* r; r = value; @@ -216,13 +218,13 @@ public unsafe static int InnerMethod(delegate* value) public class MONO_TYPE_PTR { - public unsafe static int OuterMethod() + public unsafe static int Prepare() { int a = 1; int* value = &a; - return InnerMethod(value); + return TestedMethod(value); } - public unsafe static int InnerMethod(int* value) + public unsafe static int TestedMethod(int* value) { int* r; r = value; From d0f648233165a6510b487f8a04ea3e002c40a306 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Fri, 7 May 2021 14:23:50 +0200 Subject: [PATCH 3/4] code review --- src/mono/wasm/README.md | 4 +- .../DebuggerTestSuite/AssignmentTests.cs | 234 +++--------------- .../DebuggerTestSuite/DebuggerTestBase.cs | 10 + .../wasm/debugger/tests/Directory.Build.props | 5 - .../tests/debugger-test/debugger-test.csproj | 2 - 5 files changed, 44 insertions(+), 211 deletions(-) diff --git a/src/mono/wasm/README.md b/src/mono/wasm/README.md index 913330093012c5..26a6680bccf9f1 100644 --- a/src/mono/wasm/README.md +++ b/src/mono/wasm/README.md @@ -137,7 +137,9 @@ To run a test with `FooBar` in the name: (See https://docs.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests?pivots=xunit for filter options) -Additional arguments for `dotnet test` can be passed via `TEST_ARGS`. Though only one of `TEST_ARGS`, or `TEST_FILTER` can be used at a time. +Additional arguments for `dotnet test` can be passed via `MSBUILD_ARGS` or `TEST_ARGS`. +For example `MSBUILD_ARGS="/p:WasmDebugLevel=5"` +Though only one of `TEST_ARGS`, or `TEST_FILTER` can be used at a time. ## Run samples diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs index f40b986fe25f67..00f917c8dc5731 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs @@ -11,205 +11,35 @@ namespace DebuggerTests { public class AssignmentTests : DebuggerTestBase { - [Fact] - async Task InspectObjectAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_OBJECT", - (locals) => CheckObject(locals, "r", "object", is_null: true), - (locals) => CheckObject(locals, "r", "object") - ); - } - - [Fact] - async Task InspectClassAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_CLASS", - (locals) => CheckObject(locals, "r", "DebuggerTests.MONO_TYPE_CLASS", is_null: true), - (locals) => CheckObject(locals, "r", "DebuggerTests.MONO_TYPE_CLASS") - ); - } - - [Fact] - async Task InspectBoolAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_BOOLEAN", - (locals) => CheckBool(locals, "r", default), - (locals) => CheckBool(locals, "r", true) - ); - } - - [Fact] - async Task InspectCharAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_CHAR", - (locals) => CheckSymbol(locals, "r", "0 '\u0000'"), - (locals) => CheckSymbol(locals, "r", "97 'a'") - ); - } - - [Fact] - async Task InspectSByteAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_I1", - (locals) => CheckNumber(locals, "r", default), - (locals) => CheckNumber(locals, "r", -1) - ); - } - - [Fact] - async Task InspectShortAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_I2", - (locals) => CheckNumber(locals, "r", default), - (locals) => CheckNumber(locals, "r", -1) - ); - } - - [Fact] - async Task InspectIntAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_I4", - (locals) => CheckNumber(locals, "r", default), - (locals) => CheckNumber(locals, "r", -1) - ); - } - - [Fact] - async Task InspectLongAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_I8", - (locals) => CheckNumber(locals, "r", default), - (locals) => CheckNumber(locals, "r", -1) - ); - } - - [Fact] - async Task InspectByteAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_U1", - (locals) => CheckNumber(locals, "r", default), - (locals) => CheckNumber(locals, "r", 1) - ); - } - - [Fact] - async Task InspectUShortAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_U2", - (locals) => CheckNumber(locals, "r", default), - (locals) => CheckNumber(locals, "r", 1) - ); - } - - [Fact] - async Task InspectUIntAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_U4", - (locals) => CheckNumber(locals, "r", default), - (locals) => CheckNumber(locals, "r", 1) - ); - } - - [Fact] - async Task InspectULongAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_U8", - (locals) => CheckNumber(locals, "r", default), - (locals) => CheckNumber(locals, "r", 1) - ); - } - - [Fact] - async Task InspectFloatAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_R4", - (locals) => CheckNumber(locals, "r", default), - (locals) => CheckNumber(locals, "r", 3.1415F) - ); - } - - [Fact] - async Task InspectDoubleAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_R8", - (locals) => CheckNumber(locals, "r", default), - (locals) => CheckNumber(locals, "r", 3.1415D) - ); - } - - [Fact] - async Task InspectStringAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_STRING", - (locals) => CheckString(locals, "r", default), - (locals) => CheckString(locals, "r", "hello") - ); - } - - [Fact] - async Task InspectEnumAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_ENUM", - (locals) => CheckEnum(locals, "r", "DebuggerTests.RGB", "Red"), - (locals) => CheckEnum(locals, "r", "DebuggerTests.RGB", "Blue") - ); - } - - [Fact] - async Task InspectArrayAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_ARRAY", - (locals) => CheckObject(locals, "r", "byte[]", is_null: true), - (locals) => CheckArray(locals, "r", "byte[]", 2) - ); - } - - [Fact] - async Task InspectStructAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_VALUETYPE", - (locals) => CheckValueType(locals, "r", "DebuggerTests.Point"), - (locals) => CheckValueType(locals, "r", "DebuggerTests.Point") - ); - } - - [Fact] - async Task InspectDecimalAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_VALUETYPE2", - (locals) => CheckValueType(locals, "r", "System.Decimal", description: "0"), - (locals) => CheckValueType(locals, "r", "System.Decimal", description: "1.1") - ); - } - - [Fact] - async Task InspectFunctionAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_GENERICINST", - (locals) => CheckObject(locals, "r", "System.Func", is_null: true), - (locals) => CheckObject(locals, "r", "System.Func", description: "int Prepare ()") - ); - } - - [Fact] - async Task InspectFunctionPtrAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_FNPTR", - (locals) => CheckSymbol(locals, "r", "(*()) 0"), - (locals) => { } // CheckObject(locals, "r", "(*()) 0x22dd230") // FixMe: Could we do better ? - ); - } - - [Fact] - async Task InspectIntPtrAssignmentsDuringSteppingIn() - { - await InspectAssignmentDuringSteppingIn("MONO_TYPE_PTR", - (locals) => CheckSymbol(locals, "r", "(int*) 0"), - (locals) => { } //CheckObject(locals, "r", "(int*) 0x211c058") // FixMe: Could we do better ? - ); - } - - private async Task InspectAssignmentDuringSteppingIn(string clazz, Action checkDefault, Action checkValue) + public static TheoryData GetTestData => new TheoryData + { + { "MONO_TYPE_OBJECT", TObject("object", is_null: true), TObject("object") }, + { "MONO_TYPE_CLASS", TObject("DebuggerTests.MONO_TYPE_CLASS", is_null: true), TObject("DebuggerTests.MONO_TYPE_CLASS") }, + { "MONO_TYPE_BOOLEAN", TBool(default), TBool(true) }, + { "MONO_TYPE_CHAR", TSymbol("0 '\u0000'"), TSymbol("97 'a'") }, + { "MONO_TYPE_STRING", TString(default), TString("hello") }, + { "MONO_TYPE_ENUM", TEnum("DebuggerTests.RGB", "Red"), TEnum("DebuggerTests.RGB", "Blue") }, + { "MONO_TYPE_ARRAY", TObject("byte[]", is_null: true), TArray("byte[]", 2) }, + { "MONO_TYPE_VALUETYPE", TValueType("DebuggerTests.Point"), TValueType("DebuggerTests.Point") }, + { "MONO_TYPE_VALUETYPE2", TValueType("System.Decimal","0"), TValueType("System.Decimal", "1.1") }, + { "MONO_TYPE_GENERICINST", TObject("System.Func", is_null: true), TDelegate("System.Func", "int Prepare ()") }, + { "MONO_TYPE_FNPTR", TPointer("*()", is_null: true), TPointer("*()") }, + { "MONO_TYPE_PTR", TPointer("int*", is_null: true), TPointer("int*") }, + { "MONO_TYPE_I1", TNumber(0), TNumber(-1) }, + { "MONO_TYPE_I2", TNumber(0), TNumber(-1) }, + { "MONO_TYPE_I4", TNumber(0), TNumber(-1) }, + { "MONO_TYPE_I8", TNumber(0), TNumber(-1) }, + { "MONO_TYPE_U1", TNumber(0), TNumber(1) }, + { "MONO_TYPE_U2", TNumber(0), TNumber(1) }, + { "MONO_TYPE_U4", TNumber(0), TNumber(1) }, + { "MONO_TYPE_U8", TNumber(0), TNumber(1) }, + { "MONO_TYPE_R4", TNumber(0), TNumber("3.1414999961853027") }, + { "MONO_TYPE_R8", TNumber(0), TNumber("3.1415") }, + }; + + [Theory] + [MemberData("GetTestData")] + async Task InspectVariableBeforeAndAfterAssignment(string clazz, JObject checkDefault, JObject checkValue) { await SetBreakpointInMethod("debugger-test", "DebuggerTests." + clazz, "Prepare", 2); await EvaluateAndCheck("window.setTimeout(function() { invoke_static_method('[debugger-test] DebuggerTests." + clazz + ":Prepare'); })", null, -1, -1, "Prepare"); @@ -218,9 +48,8 @@ private async Task InspectAssignmentDuringSteppingIn(string clazz, Action { - Console.WriteLine(locals); Assert.Equal(2, locals.Count()); - checkDefault(locals); + Check(locals, "r", checkDefault); } ); @@ -228,9 +57,8 @@ await StepAndCheck(StepKind.Into, "dotnet://debugger-test.dll/debugger-assignmen await StepAndCheck(StepKind.Over, "dotnet://debugger-test.dll/debugger-assignment-test.cs", -1, -1, "TestedMethod", times: 3, locals_fn: (locals) => { - Console.WriteLine(locals); Assert.Equal(2, locals.Count()); - checkValue(locals); + Check(locals, "r", checkValue); } ); } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs index a89c292d992a1e..2056d581b3b6d0 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs @@ -259,6 +259,13 @@ internal JToken CheckSymbol(JToken locals, string name, string value) return l; } + internal JToken Check(JToken locals, string name, JObject expected) + { + var l = GetAndAssertObjectWithName(locals, name); + CheckValue(l["value"], expected, name).Wait(); + return l; + } + internal JToken CheckObject(JToken locals, string name, string class_name, string subtype = null, bool is_null = false, string description = null) { var l = GetAndAssertObjectWithName(locals, name); @@ -933,6 +940,9 @@ internal static JObject TNumber(int value) => internal static JObject TNumber(uint value) => JObject.FromObject(new { type = "number", value = @value.ToString(), description = value.ToString() }); + internal static JObject TNumber(string value) => + JObject.FromObject(new { type = "number", value = @value.ToString(), description = value }); + internal static JObject TValueType(string className, string description = null, object members = null) => JObject.FromObject(new { type = "object", isValueType = true, className = className, description = description ?? className }); diff --git a/src/mono/wasm/debugger/tests/Directory.Build.props b/src/mono/wasm/debugger/tests/Directory.Build.props index 3b6a8dd44b0b65..0cff1f10a52d40 100644 --- a/src/mono/wasm/debugger/tests/Directory.Build.props +++ b/src/mono/wasm/debugger/tests/Directory.Build.props @@ -16,9 +16,4 @@ $(ArtifactsBinDir)microsoft.netcore.app.runtime.browser-wasm\$(RuntimeConfiguration)\runtimes\browser-wasm\ - - - 5 - - diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj index 3e13d2154e3814..648dbcc64fc6da 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj @@ -36,8 +36,6 @@ - - From 516a769208e1e1e6c6b21506a76c483380a25799 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Fri, 7 May 2021 16:21:31 +0200 Subject: [PATCH 4/4] lint --- src/mono/wasm/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mono/wasm/README.md b/src/mono/wasm/README.md index 26a6680bccf9f1..6a5dff401ab210 100644 --- a/src/mono/wasm/README.md +++ b/src/mono/wasm/README.md @@ -137,9 +137,7 @@ To run a test with `FooBar` in the name: (See https://docs.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests?pivots=xunit for filter options) -Additional arguments for `dotnet test` can be passed via `MSBUILD_ARGS` or `TEST_ARGS`. -For example `MSBUILD_ARGS="/p:WasmDebugLevel=5"` -Though only one of `TEST_ARGS`, or `TEST_FILTER` can be used at a time. +Additional arguments for `dotnet test` can be passed via `MSBUILD_ARGS` or `TEST_ARGS`. For example `MSBUILD_ARGS="/p:WasmDebugLevel=5"`. Though only one of `TEST_ARGS`, or `TEST_FILTER` can be used at a time. ## Run samples