Skip to content

Commit 5fe7b06

Browse files
authored
[wasm][debugger] Showing "Frame not in module" after vscode-js-debug bump on VS (#87154)
* 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
1 parent 01f63e7 commit 5fe7b06

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public FirefoxMonoProxy(ILogger logger, string loggerId = null, ProxyOptions opt
2323

2424
public FirefoxExecutionContext GetContextFixefox(SessionId sessionId)
2525
{
26-
if (contexts.TryGetValue(sessionId, out ExecutionContext context))
26+
if (TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
2727
return context as FirefoxExecutionContext;
2828
throw new ArgumentException($"Invalid Session: \"{sessionId}\"", nameof(sessionId));
2929
}
@@ -316,7 +316,7 @@ protected override async Task<bool> AcceptCommand(MessageId sessionId, JObject a
316316
{
317317
case "resume":
318318
{
319-
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
319+
if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
320320
return false;
321321
context.PausedOnWasm = false;
322322
if (context.CallStack == null)
@@ -380,7 +380,7 @@ protected override async Task<bool> AcceptCommand(MessageId sessionId, JObject a
380380
}
381381
case "setBreakpoint":
382382
{
383-
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
383+
if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
384384
return false;
385385
var req = JObject.FromObject(new
386386
{
@@ -420,7 +420,7 @@ protected override async Task<bool> AcceptCommand(MessageId sessionId, JObject a
420420
}
421421
case "removeBreakpoint":
422422
{
423-
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
423+
if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
424424
return false;
425425
Result resp = await SendCommand(sessionId, "", args, token);
426426

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

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ internal class MonoProxy : DevToolsProxy
2424
internal string CachePathSymbolServer { get; private set; }
2525
private readonly HashSet<SessionId> sessions = new HashSet<SessionId>();
2626
private static readonly string[] s_executionContextIndependentCDPCommandNames = { "DotnetDebugger.setDebuggerProperty", "DotnetDebugger.runTests" };
27-
protected Dictionary<SessionId, ExecutionContext> contexts = new Dictionary<SessionId, ExecutionContext>();
27+
protected Dictionary<SessionId, List<ExecutionContext>> contexts = new Dictionary<SessionId, List<ExecutionContext>>();
2828

2929
public static HttpClient HttpClient => new HttpClient();
3030

@@ -45,24 +45,37 @@ public MonoProxy(ILogger logger, int runtimeId = 0, string loggerId = "", ProxyO
4545

4646
internal ExecutionContext GetContext(SessionId sessionId)
4747
{
48-
if (contexts.TryGetValue(sessionId, out ExecutionContext context))
48+
if (TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
4949
return context;
5050

5151
throw new ArgumentException($"Invalid Session: \"{sessionId}\"", nameof(sessionId));
5252
}
5353

5454
private bool UpdateContext(SessionId sessionId, ExecutionContext executionContext, out ExecutionContext previousExecutionContext)
5555
{
56-
bool previous = contexts.TryGetValue(sessionId, out previousExecutionContext);
57-
contexts[sessionId] = executionContext;
56+
bool previous = TryGetCurrentExecutionContextValue(sessionId, out previousExecutionContext);
57+
if (!previous)
58+
contexts[sessionId] = new();
59+
contexts[sessionId].Add(executionContext);
5860
return previous;
5961
}
6062

63+
internal bool TryGetCurrentExecutionContextValue(SessionId id, out ExecutionContext executionContext)
64+
{
65+
executionContext = null;
66+
if (!contexts.TryGetValue(id, out List<ExecutionContext> contextList))
67+
return false;
68+
if (contextList.Count == 0)
69+
return false;
70+
executionContext = contextList.Last<ExecutionContext>();
71+
return true;
72+
}
73+
6174
internal virtual Task<Result> SendMonoCommand(SessionId id, MonoCommands cmd, CancellationToken token) => SendCommand(id, "Runtime.evaluate", JObject.FromObject(cmd), token);
6275

6376
internal void SendLog(SessionId sessionId, string message, CancellationToken token, string type = "warning")
6477
{
65-
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
78+
if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
6679
return;
6780
/*var o = JObject.FromObject(new
6881
{
@@ -151,6 +164,16 @@ protected override async Task<bool> AcceptEvent(SessionId sessionId, JObject par
151164
}
152165
return true;
153166
}
167+
case "Runtime.executionContextDestroyed":
168+
{
169+
int id = args["executionContextId"].Value<int>();
170+
if (!contexts.TryGetValue(sessionId, out var contextList))
171+
return false;
172+
contextList.RemoveAll(x => x.Id == id);
173+
if (contextList.Count == 0)
174+
contexts.Remove(sessionId);
175+
return false;
176+
}
154177

155178
case "Debugger.paused":
156179
{
@@ -188,7 +211,7 @@ protected async Task<bool> OnDebuggerPaused(SessionId sessionId, JObject args, C
188211

189212
if (args["asyncStackTraceId"] != null)
190213
{
191-
if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
214+
if (!TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context))
192215
return false;
193216
if (context.CopyDataFromParentContext())
194217
{
@@ -254,7 +277,7 @@ protected async Task<bool> OnDebuggerPaused(SessionId sessionId, JObject args, C
254277

255278
protected void CreateWorkerExecutionContext(SessionId workerSessionId, SessionId originSessionId)
256279
{
257-
if (!contexts.TryGetValue(originSessionId, out ExecutionContext context))
280+
if (!TryGetCurrentExecutionContextValue(originSessionId, out ExecutionContext context))
258281
{
259282
logger.LogDebug($"Origin sessionId does not exist - {originSessionId}");
260283
return;
@@ -264,7 +287,8 @@ protected void CreateWorkerExecutionContext(SessionId workerSessionId, SessionId
264287
logger.LogDebug($"Worker sessionId already exists - {originSessionId}");
265288
return;
266289
}
267-
contexts[workerSessionId] = context.CreateChildAsyncExecutionContext(workerSessionId);
290+
contexts[workerSessionId] = new();
291+
contexts[workerSessionId].Add(context.CreateChildAsyncExecutionContext(workerSessionId));
268292
}
269293

270294
protected virtual async Task SendResume(SessionId id, CancellationToken token)
@@ -273,7 +297,7 @@ protected virtual async Task SendResume(SessionId id, CancellationToken token)
273297
}
274298
protected async Task<bool> IsRuntimeAlreadyReadyAlready(SessionId sessionId, CancellationToken token)
275299
{
276-
if (contexts.TryGetValue(sessionId, out ExecutionContext context) && context.IsRuntimeReady)
300+
if (TryGetCurrentExecutionContextValue(sessionId, out ExecutionContext context) && context.IsRuntimeReady)
277301
return true;
278302

279303
Result res = await SendMonoCommand(sessionId, MonoCommands.IsRuntimeReady(RuntimeId), token);
@@ -298,7 +322,7 @@ protected override async Task<bool> AcceptCommand(MessageId id, JObject parms, C
298322
if (id == SessionId.Null)
299323
await AttachToTarget(id, token);
300324

301-
if (!contexts.TryGetValue(id, out ExecutionContext context) && !s_executionContextIndependentCDPCommandNames.Contains(method))
325+
if (!TryGetCurrentExecutionContextValue(id, out ExecutionContext context) && !s_executionContextIndependentCDPCommandNames.Contains(method))
302326
{
303327
if (method == "Debugger.setPauseOnExceptions")
304328
{

0 commit comments

Comments
 (0)