diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index 6c1ad7cf757d9f..013fd92970a30e 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -1216,11 +1216,7 @@ private async Task RuntimeReady(SessionId sessionId, CancellationTok return await context.ready.Task; var commandParams = new MemoryStream(); - var retDebuggerCmdReader = await SdbHelper.SendDebuggerAgentCommand(sessionId, CmdEventRequest.ClearAllBreakpoints, commandParams, token); - if (retDebuggerCmdReader == null) - { - Log("verbose", $"Failed to clear breakpoints"); - } + await SdbHelper.SendDebuggerAgentCommand(sessionId, CmdEventRequest.ClearAllBreakpoints, commandParams, token); if (context.PauseOnExceptions != PauseOnExceptionsKind.None && context.PauseOnExceptions != PauseOnExceptionsKind.Unset) await SdbHelper.EnableExceptions(sessionId, context.PauseOnExceptions, token); @@ -1233,7 +1229,7 @@ private async Task RuntimeReady(SessionId sessionId, CancellationTok DebugStore store = await LoadStore(sessionId, token); context.ready.SetResult(store); SendEvent(sessionId, "Mono.runtimeReady", new JObject(), token); - SdbHelper.SetStore(store); + SdbHelper.ResetStore(store); return store; } diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index 9534d306eef5ed..dee4b5ac0f5fde 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -379,7 +379,11 @@ public TypeInfoWithDebugInformation(TypeInfo typeInfo, int debugId, string name) internal class MonoBinaryReader : BinaryReader { - public MonoBinaryReader(Stream stream) : base(stream) {} + public bool HasError { get; } + public MonoBinaryReader(Stream stream, bool hasError = false) : base(stream) + { + HasError = hasError; + } internal static unsafe void PutBytesBE (byte *dest, byte *src, int count) { @@ -656,9 +660,9 @@ internal class MonoSDBHelper private static int MINOR_VERSION = 61; private static int MAJOR_VERSION = 2; - private Dictionary methods = new(); - private Dictionary assemblies = new(); - private Dictionary types = new(); + private Dictionary methods; + private Dictionary assemblies; + private Dictionary types; internal Dictionary valueTypes = new Dictionary(); internal Dictionary pointerValues = new Dictionary(); @@ -673,12 +677,16 @@ public MonoSDBHelper(MonoProxy proxy, ILogger logger) { this.proxy = proxy; this.logger = logger; - this.store = null; + ResetStore(null); } - public void SetStore(DebugStore store) + public void ResetStore(DebugStore store) { this.store = store; + this.methods = new(); + this.assemblies = new(); + this.types = new(); + ClearCache(); } public async Task GetAssemblyInfo(SessionId sessionId, int assemblyId, CancellationToken token) @@ -816,12 +824,12 @@ public async Task EnableReceiveRequests(SessionId sessionId, EventKind eve internal async Task SendDebuggerAgentCommandInternal(SessionId sessionId, int command_set, int command, MemoryStream parms, CancellationToken token) { Result res = await proxy.SendMonoCommand(sessionId, MonoCommands.SendDebuggerAgentCommand(GetId(), command_set, command, Convert.ToBase64String(parms.ToArray())), token); - if (res.IsErr) { - throw new Exception($"SendDebuggerAgentCommand Error - {(CommandSet)command_set} - {command}"); + byte[] newBytes = Array.Empty(); + if (!res.IsErr) { + newBytes = Convert.FromBase64String(res.Value?["result"]?["value"]?["value"]?.Value()); } - byte[] newBytes = Convert.FromBase64String(res.Value?["result"]?["value"]?["value"]?.Value()); var retDebuggerCmd = new MemoryStream(newBytes); - var retDebuggerCmdReader = new MonoBinaryReader(retDebuggerCmd); + var retDebuggerCmdReader = new MonoBinaryReader(retDebuggerCmd, res.IsErr); return retDebuggerCmdReader; } @@ -854,12 +862,12 @@ internal Task SendDebuggerAgentCommandWithParms(SessionId s internal async Task SendDebuggerAgentCommandWithParmsInternal(SessionId sessionId, int command_set, int command, MemoryStream parms, int type, string extraParm, CancellationToken token) { Result res = await proxy.SendMonoCommand(sessionId, MonoCommands.SendDebuggerAgentCommandWithParms(GetId(), command_set, command, Convert.ToBase64String(parms.ToArray()), parms.ToArray().Length, type, extraParm), token); - if (res.IsErr) { - throw new Exception("SendDebuggerAgentCommandWithParms Error"); + byte[] newBytes = Array.Empty(); + if (!res.IsErr) { + newBytes = Convert.FromBase64String(res.Value?["result"]?["value"]?["value"]?.Value()); } - byte[] newBytes = Convert.FromBase64String(res.Value?["result"]?["value"]?["value"]?.Value()); var retDebuggerCmd = new MemoryStream(newBytes); - var retDebuggerCmdReader = new MonoBinaryReader(retDebuggerCmd); + var retDebuggerCmdReader = new MonoBinaryReader(retDebuggerCmd, res.IsErr); return retDebuggerCmdReader; } @@ -2530,15 +2538,9 @@ public async Task SetVariableValue(SessionId sessionId, int thread_id, int JArray locals = new JArray(); retDebuggerCmdReader = await SendDebuggerAgentCommand(sessionId, CmdFrame.GetValues, commandParams, token); int etype = retDebuggerCmdReader.ReadByte(); - try - { - retDebuggerCmdReader = await SendDebuggerAgentCommandWithParms(sessionId, CmdFrame.SetValues, commandParams, etype, newValue, token); - } - catch (Exception) - { + retDebuggerCmdReader = await SendDebuggerAgentCommandWithParms(sessionId, CmdFrame.SetValues, commandParams, etype, newValue, token); + if (retDebuggerCmdReader.HasError) return false; - } - return true; } } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs index 6e9d420801dd9a..60cd0242bfddcc 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/BreakpointTests.cs @@ -8,6 +8,7 @@ using Newtonsoft.Json.Linq; using System.IO; using Xunit; +using System.Threading; namespace DebuggerTests { @@ -131,11 +132,6 @@ public async Task CreateGoodBreakpointAndHit() { var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8); - var eval_req = JObject.FromObject(new - { - expression = "window.setTimeout(function() { invoke_add(); }, 1);", - }); - await EvaluateAndCheck( "window.setTimeout(function() { invoke_add(); }, 1);", "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, @@ -577,5 +573,74 @@ await SendCommandAndCheck(null, "Debugger.resume", CheckNumber(locals, "i", 2); }); } + + [Fact] + public async Task CreateGoodBreakpointAndHitGoToNonWasmPageComeBackAndHitAgain() + { + var bp = await SetBreakpoint("dotnet://debugger-test.dll/debugger-test.cs", 10, 8); + var pause_location = await EvaluateAndCheck( + "window.setTimeout(function() { invoke_add(); }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, + "IntAdd"); + Assert.Equal("other", pause_location["reason"]?.Value()); + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value()); + + var top_frame = pause_location["callFrames"][0]; + Assert.Equal("IntAdd", top_frame["functionName"].Value()); + Assert.Contains("debugger-test.cs", top_frame["url"].Value()); + + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, top_frame["functionLocation"]); + + //now check the scope + var scope = top_frame["scopeChain"][0]; + Assert.Equal("local", scope["type"]); + Assert.Equal("IntAdd", scope["name"]); + + Assert.Equal("object", scope["object"]["type"]); + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, scope["startLocation"]); + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 14, 4, scripts, scope["endLocation"]); + + await cli.SendCommand("Debugger.resume", null, token); + + var run_method = JObject.FromObject(new + { + expression = "window.setTimeout(function() { load_non_wasm_page(); }, 1);" + }); + await cli.SendCommand("Runtime.evaluate", run_method, token); + await Task.Delay(1000, token); + + run_method = JObject.FromObject(new + { + expression = "window.setTimeout(function() { reload_wasm_page(); }, 1);" + }); + await cli.SendCommand("Runtime.evaluate", run_method, token); + await insp.WaitFor(Inspector.READY); + await EvaluateAndCheck( + "window.setTimeout(function() { invoke_add(); }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 10, 8, + "IntAdd", + wait_for_event_fn: (pause_location) => + { + Assert.Equal("other", pause_location["reason"]?.Value()); + Assert.Equal(bp.Value["breakpointId"]?.ToString(), pause_location["hitBreakpoints"]?[0]?.Value()); + + var top_frame = pause_location["callFrames"][0]; + Assert.Equal("IntAdd", top_frame["functionName"].Value()); + Assert.Contains("debugger-test.cs", top_frame["url"].Value()); + + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, top_frame["functionLocation"]); + + //now check the scope + var scope = top_frame["scopeChain"][0]; + Assert.Equal("local", scope["type"]); + Assert.Equal("IntAdd", scope["name"]); + + Assert.Equal("object", scope["object"]["type"]); + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 8, 4, scripts, scope["startLocation"]); + CheckLocation("dotnet://debugger-test.dll/debugger-test.cs", 14, 4, scripts, scope["endLocation"]); + return Task.CompletedTask; + } + ); + } } } diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-driver.html b/src/mono/wasm/debugger/tests/debugger-test/debugger-driver.html index b1bfcd859d0644..ddf5dc54e48ead 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-driver.html +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-driver.html @@ -1,8 +1,8 @@ - - - + + + - - - - Stuff goes here - - + + function load_non_wasm_page () { + console.log("load_non_wasm_page") + window.location.replace("http://localhost:9400/non-wasm-page.html"); + } + + + + + Stuff goes here + + 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 bf098dd83f578f..145c80e8c20fc6 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj @@ -10,6 +10,7 @@ + diff --git a/src/mono/wasm/debugger/tests/debugger-test/non-wasm-page.html b/src/mono/wasm/debugger/tests/debugger-test/non-wasm-page.html new file mode 100644 index 00000000000000..2894375a79c809 --- /dev/null +++ b/src/mono/wasm/debugger/tests/debugger-test/non-wasm-page.html @@ -0,0 +1,12 @@ + + + + + + + +