diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/Firefox/FirefoxMonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/Firefox/FirefoxMonoProxy.cs index deb9761130b3cc..fb862b9747acc6 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/Firefox/FirefoxMonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/Firefox/FirefoxMonoProxy.cs @@ -23,7 +23,7 @@ public FirefoxMonoProxy(ILogger logger, string loggerId = null, ProxyOptions opt public FirefoxExecutionContext GetContextFixefox(SessionId sessionId) { - if (contexts.TryGetValue(sessionId, out ExecutionContext context)) + if (TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context)) return context as FirefoxExecutionContext; throw new ArgumentException($"Invalid Session: \"{sessionId}\"", nameof(sessionId)); } @@ -334,7 +334,7 @@ protected override async Task AcceptCommand(MessageId sessionId, JObject a { case "resume": { - if (!contexts.TryGetValue(sessionId, out ExecutionContext context)) + if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context)) return false; context.PausedOnWasm = false; if (context.CallStack == null) @@ -396,7 +396,7 @@ protected override async Task AcceptCommand(MessageId sessionId, JObject a } case "setBreakpoint": { - if (!contexts.TryGetValue(sessionId, out ExecutionContext context)) + if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context)) return false; var req = JObject.FromObject(new { @@ -436,7 +436,7 @@ protected override async Task AcceptCommand(MessageId sessionId, JObject a } case "removeBreakpoint": { - if (!contexts.TryGetValue(sessionId, out ExecutionContext context)) + if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context)) return false; Result resp = await SendCommand(sessionId, "", args, token); diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index 15682c6dad1e30..38dd1997c14fef 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -20,7 +20,7 @@ internal class MonoProxy : DevToolsProxy { private IList urlSymbolServerList; private HashSet sessions = new HashSet(); - protected Dictionary contexts = new Dictionary(); + protected Dictionary> contexts = new Dictionary>(); public static HttpClient HttpClient => new HttpClient(); @@ -41,7 +41,7 @@ public MonoProxy(ILogger logger, IList urlSymbolServerList, int runtimeI internal ExecutionContext GetContext(SessionId sessionId) { - if (contexts.TryGetValue(sessionId, out ExecutionContext context)) + if (TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context)) return context; throw new ArgumentException($"Invalid Session: \"{sessionId}\"", nameof(sessionId)); @@ -49,16 +49,29 @@ internal ExecutionContext GetContext(SessionId sessionId) private bool UpdateContext(SessionId sessionId, ExecutionContext executionContext, out ExecutionContext previousExecutionContext) { - bool previous = contexts.TryGetValue(sessionId, out previousExecutionContext); - contexts[sessionId] = executionContext; + bool previous = TryGetCurrentExecutionContextValue(sessionId, out previousExecutionContext); + if (!previous) + contexts[sessionId] = new(); + contexts[sessionId].Add(executionContext); return previous; } + internal bool TryGetCurrentExecutionContextValue(SessionId id, out ExecutionContext executionContext) + { + executionContext = null; + if (!contexts.TryGetValue(id, out List contextList)) + return false; + if (contextList.Count == 0) + return false; + executionContext = contextList.Last(); + return true; + } + internal virtual Task SendMonoCommand(SessionId id, MonoCommands cmd, CancellationToken token) => SendCommand(id, "Runtime.evaluate", JObject.FromObject(cmd), token); internal void SendLog(SessionId sessionId, string message, CancellationToken token, string type = "warning") { - if (!contexts.TryGetValue(sessionId, out ExecutionContext context)) + if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context)) return; /*var o = JObject.FromObject(new { @@ -93,7 +106,7 @@ protected override async Task AcceptEvent(SessionId sessionId, JObject par case "Runtime.consoleAPICalled": { // Don't process events from sessions we aren't tracking - if (!contexts.TryGetValue(sessionId, out ExecutionContext context)) + if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context)) return false; string type = args["type"]?.ToString(); if (type == "debug") @@ -169,6 +182,17 @@ protected override async Task AcceptEvent(SessionId sessionId, JObject par return true; } + case "Runtime.executionContextDestroyed": + { + int id = args["executionContextId"].Value(); + if (!contexts.TryGetValue(sessionId, out var contextList)) + return false; + contextList.RemoveAll(x => x.Id == id); + if (contextList.Count == 0) + contexts.Remove(sessionId); + return false; + } + case "Debugger.paused": { // Don't process events from sessions we aren't tracking @@ -254,7 +278,7 @@ protected virtual async Task SendResume(SessionId id, CancellationToken token) } protected async Task IsRuntimeAlreadyReadyAlready(SessionId sessionId, CancellationToken token) { - if (contexts.TryGetValue(sessionId, out ExecutionContext context) && context.IsRuntimeReady) + if (TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context) && context.IsRuntimeReady) return true; Result res = await SendMonoCommand(sessionId, MonoCommands.IsRuntimeReady(RuntimeId), token); @@ -277,7 +301,7 @@ protected override async Task AcceptCommand(MessageId id, JObject parms, C if (id == SessionId.Null) await AttachToTarget(id, token); - if (!contexts.TryGetValue(id, out ExecutionContext context)) + if (!TryGetCurrentExecutionContextValue(id, out ExecutionContext context)) { if (method == "Debugger.setPauseOnExceptions") {