[wasm][debugger] Showing "Frame not in module" after vscode-js-debug bump on VS ...
authorThays Grazia <thaystg@gmail.com>
Mon, 19 Jun 2023 10:28:05 +0000 (07:28 -0300)
committerGitHub <noreply@github.com>
Mon, 19 Jun 2023 10:28:05 +0000 (12:28 +0200)
* We were sending the scriptId of a context that was already destroyed and vscode-js-debug extension started to consider this information that was ignored before.

* addressing @radical comments

src/mono/wasm/debugger/BrowserDebugProxy/Firefox/FirefoxMonoProxy.cs
src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs

index 25c7dc8a3a9d049b86b1d4bb8147acf43563f66b..8c8605cf25f726d6bd3d94827bca2425fb84271c 100644 (file)
@@ -23,7 +23,7 @@ internal sealed class FirefoxMonoProxy : MonoProxy
 
     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));
     }
@@ -316,7 +316,7 @@ internal sealed class FirefoxMonoProxy : MonoProxy
         {
             case "resume":
                 {
-                    if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
+                    if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
                         return false;
                     context.PausedOnWasm = false;
                     if (context.CallStack == null)
@@ -380,7 +380,7 @@ internal sealed class FirefoxMonoProxy : MonoProxy
                 }
             case "setBreakpoint":
                 {
-                    if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
+                    if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
                         return false;
                     var req = JObject.FromObject(new
                     {
@@ -420,7 +420,7 @@ internal sealed class FirefoxMonoProxy : MonoProxy
                 }
             case "removeBreakpoint":
                 {
-                    if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
+                    if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
                         return false;
                     Result resp = await SendCommand(sessionId, "", args, token);
 
index 11cc46f7978f7c9eeeade6261bacce551edb6b3f..ed2495c469cf35cdfb2c2b24b380a487bebf57a5 100644 (file)
@@ -24,7 +24,7 @@ namespace Microsoft.WebAssembly.Diagnostics
         internal string CachePathSymbolServer { get; private set; }
         private readonly HashSet<SessionId> sessions = new HashSet<SessionId>();
         private static readonly string[] s_executionContextIndependentCDPCommandNames = { "DotnetDebugger.setDebuggerProperty", "DotnetDebugger.runTests" };
-        protected Dictionary<SessionId, ExecutionContext> contexts = new Dictionary<SessionId, ExecutionContext>();
+        protected Dictionary<SessionId, List<ExecutionContext>> contexts = new Dictionary<SessionId, List<ExecutionContext>>();
 
         public static HttpClient HttpClient => new HttpClient();
 
@@ -45,7 +45,7 @@ namespace Microsoft.WebAssembly.Diagnostics
 
         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));
@@ -53,16 +53,29 @@ namespace Microsoft.WebAssembly.Diagnostics
 
         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<ExecutionContext> contextList))
+                return false;
+            if (contextList.Count == 0)
+                return false;
+            executionContext = contextList.Last<ExecutionContext>();
+            return true;
+        }
+
         internal virtual Task<Result> 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
             {
@@ -151,6 +164,16 @@ namespace Microsoft.WebAssembly.Diagnostics
                         }
                         return true;
                     }
+                case "Runtime.executionContextDestroyed":
+                    {
+                        int id = args["executionContextId"].Value<int>();
+                        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":
                     {
@@ -188,7 +211,7 @@ namespace Microsoft.WebAssembly.Diagnostics
 
             if (args["asyncStackTraceId"] != null)
             {
-                if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
+                if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
                     return false;
                 if (context.CopyDataFromParentContext())
                 {
@@ -254,7 +277,7 @@ namespace Microsoft.WebAssembly.Diagnostics
 
         protected void CreateWorkerExecutionContext(SessionId workerSessionId, SessionId originSessionId)
         {
-            if (!contexts.TryGetValue(originSessionId, out ExecutionContext context))
+            if (!TryGetCurrentExecutionContextValue(originSessionId, out ExecutionContext context))
             {
                 logger.LogDebug($"Origin sessionId does not exist - {originSessionId}");
                 return;
@@ -264,7 +287,8 @@ namespace Microsoft.WebAssembly.Diagnostics
                 logger.LogDebug($"Worker sessionId already exists - {originSessionId}");
                 return;
             }
-            contexts[workerSessionId] = context.CreateChildAsyncExecutionContext(workerSessionId);
+            contexts[workerSessionId] = new();
+            contexts[workerSessionId].Add(context.CreateChildAsyncExecutionContext(workerSessionId));
         }
 
         protected virtual async Task SendResume(SessionId id, CancellationToken token)
@@ -273,7 +297,7 @@ namespace Microsoft.WebAssembly.Diagnostics
         }
         protected async Task<bool> 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);
@@ -298,7 +322,7 @@ namespace Microsoft.WebAssembly.Diagnostics
             if (id == SessionId.Null)
                 await AttachToTarget(id, token);
 
-            if (!contexts.TryGetValue(id, out ExecutionContext context) && !s_executionContextIndependentCDPCommandNames.Contains(method))
+            if (!TryGetCurrentExecutionContextValue(id, out ExecutionContext context) && !s_executionContextIndependentCDPCommandNames.Contains(method))
             {
                 if (method == "Debugger.setPauseOnExceptions")
                 {