Skip to content

Commit 75f6a52

Browse files
authored
Merge pull request #2106 from microsoft/connor4312/fix-bad-wasm-breaks
fix: ignore extra pauses during wasm compilation
2 parents f2882f2 + 0bea134 commit 75f6a52

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

src/adapter/threads.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,12 @@ export class Thread implements IVariableStoreLocationProvider {
923923
const context = new ExecutionContext(description);
924924
this._executionContexts.set(description.id, context);
925925

926+
if (this._scriptWithSourceMapHandler) {
927+
this._installWasmPauseHandler(description.id);
928+
}
929+
}
930+
931+
private _installWasmPauseHandler(contextId: number) {
926932
// WASM files don't have sourcemaps and so aren't paused in the usual
927933
// instrumentation BP. But we do need to pause, either to figure out the WAT
928934
// lines or by mapping symbolicated files.
@@ -937,14 +943,14 @@ export class Thread implements IVariableStoreLocationProvider {
937943
// }),
938944
//
939945
// For now, overwrite WebAssembly methods in the runtime to get the same effect. This needs to be run in event new execution context:
940-
this._cdp.Runtime.evaluate({
946+
return this._cdp.Runtime.evaluate({
941947
expression: breakOnWasmInit.expr(),
942948
silent: true,
943-
contextId: description.id,
949+
contextId,
944950
});
945951
}
946952

947-
async _executionContextDestroyed(contextId: number) {
953+
private async _executionContextDestroyed(contextId: number) {
948954
const context = this._executionContexts.get(contextId);
949955
if (!context) return;
950956
this._executionContexts.delete(contextId);
@@ -1016,13 +1022,18 @@ export class Thread implements IVariableStoreLocationProvider {
10161022
}
10171023

10181024
const expectedPauseReason = this._expectedPauseReason;
1019-
if (isWasmBreak && this._lastParsedWasmScriptIds) {
1025+
if (isWasmBreak) {
10201026
// Resolve all pending WASM symbols when we've just initialized something
10211027
const ids = this._lastParsedWasmScriptIds;
10221028
this._lastParsedWasmScriptIds = undefined;
1023-
await Promise.all(
1024-
ids.map(id => this._handleSourceMapPause(id, location)),
1025-
);
1029+
// In theory `ids` should always have something, but it seems like we
1030+
// can see (and ignore) multiple scriptParsed events with the same ID
1031+
// for the same program if it's WebAssembly.compile'd multiple times.
1032+
if (ids) {
1033+
await Promise.all(
1034+
ids.map(id => this._handleSourceMapPause(id, location)),
1035+
);
1036+
}
10261037
return this.resume();
10271038
} else if (scriptId && (await this._handleSourceMapPause(scriptId, location))) {
10281039
// Pause if we just resolved a breakpoint that's on this
@@ -1979,12 +1990,15 @@ export class Thread implements IVariableStoreLocationProvider {
19791990
// setting the URL breakpoint for wasm fails if debugger isn't fully initialized
19801991
await this.debuggerReady.promise;
19811992

1993+
const wasmHandlers = Promise.all([...this._executionContexts.keys()]
1994+
.map(id => this._installWasmPauseHandler(id)));
19821995
const result = await Promise.all([
19831996
this._cdp.Debugger.setInstrumentationBreakpoint({
19841997
instrumentation: 'beforeScriptWithSourceMapExecution',
19851998
}),
19861999
]);
19872000
this._pauseOnSourceMapBreakpointIds = result.map(r => r?.breakpointId).filter(truthy);
2001+
await wasmHandlers;
19882002
} else if (!needsPause && this._pauseOnSourceMapBreakpointIds?.length) {
19892003
const breakpointIds = this._pauseOnSourceMapBreakpointIds;
19902004
this._pauseOnSourceMapBreakpointIds = undefined;

0 commit comments

Comments
 (0)