From fc778e62a1ea158e151000be0889d50f4701a293 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Thu, 3 Oct 2024 16:40:40 -0700 Subject: [PATCH] fix: disable entrypoint breakpoint at first pause in script (#2094) Fixes https://github.com/microsoft/vscode/issues/230201 --- src/adapter/breakpoints.ts | 13 ++++++++++ src/adapter/threads.ts | 2 ++ ...t-breakpoint-when-in-file-vscode230201.txt | 7 ++++++ src/test/breakpoints/breakpointsTest.ts | 25 +++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 src/test/breakpoints/breakpoints-disables-entrypoint-breakpoint-when-in-file-vscode230201.txt diff --git a/src/adapter/breakpoints.ts b/src/adapter/breakpoints.ts index f50cff07a..b22950d11 100644 --- a/src/adapter/breakpoints.ts +++ b/src/adapter/breakpoints.ts @@ -714,6 +714,19 @@ export class BreakpointManager { }); } + /** + * Disables entrypoint breakpoints set in the given script ID. This is + * needed so they don't vote to continue later + * @see https://github.com/microsoft/vscode/issues/230201 + */ + public async disableEntrypointBreaks(scriptId: string) { + await Promise.all([...this.moduleEntryBreakpoints.values()].map(bp => { + if (bp.enabled && bp.cdpScriptIds.has(scriptId)) { + return bp.disable(); + } + })); + } + /** Gets whether the CDP breakpoint ID refers to an entrypoint breakpoint. */ public isEntrypointCdpBreak(cdpId: string) { const bp = this._resolvedBreakpoints.get(cdpId); diff --git a/src/adapter/threads.ts b/src/adapter/threads.ts index ed6e408a7..a81ee3656 100644 --- a/src/adapter/threads.ts +++ b/src/adapter/threads.ts @@ -1721,6 +1721,7 @@ export class Thread implements IVariableStoreLocationProvider { } const timer = new HrTime(); + const disableProm = this._breakpointManager.disableEntrypointBreaks(scriptId); const result = await Promise.race([this._getOrStartLoadingSourceMaps(script), delay(timeout)]); const timeSpentWallClockInMs = timer.elapsed().ms; @@ -1751,6 +1752,7 @@ export class Thread implements IVariableStoreLocationProvider { console.assert(this._pausedForSourceMapScriptId === scriptId); this._pausedForSourceMapScriptId = undefined; + await disableProm; const bLine = brokenOn?.lineNumber || 0; const bColumn = brokenOn?.columnNumber; diff --git a/src/test/breakpoints/breakpoints-disables-entrypoint-breakpoint-when-in-file-vscode230201.txt b/src/test/breakpoints/breakpoints-disables-entrypoint-breakpoint-when-in-file-vscode230201.txt new file mode 100644 index 000000000..2eba1b762 --- /dev/null +++ b/src/test/breakpoints/breakpoints-disables-entrypoint-breakpoint-when-in-file-vscode230201.txt @@ -0,0 +1,7 @@ +{ + allThreadsStopped : false + description : Paused + reason : step + threadId : +} + @ ${fixturesDir}/test.js:5:1 diff --git a/src/test/breakpoints/breakpointsTest.ts b/src/test/breakpoints/breakpointsTest.ts index fa1485ea7..dd2811a02 100644 --- a/src/test/breakpoints/breakpointsTest.ts +++ b/src/test/breakpoints/breakpointsTest.ts @@ -1414,4 +1414,29 @@ describe('breakpoints', () => { await waitForPause(p); p.assertLog(); }); + + itIntegrates('disables entrypoint breakpoint when in file (vscode#230201)', async ({ r }) => { + createFileTree(testFixturesDir, { + 'test.js': `function firstfunc(arg){ + return arg * arg +} +const a = firstfunc(2); +console.log('Finished awesome program');`, + }); + + const handle = await r.runScript('test.js', { + cwd: testFixturesDir, + }); + + await handle.dap.setBreakpoints({ + source: { path: join(testFixturesDir, 'test.js') }, + breakpoints: [{ line: 4, column: 1 }], + }); + + handle.load(); + const { threadId } = await handle.dap.once('stopped'); + await handle.dap.next({ threadId: threadId! }); + await waitForPause(handle); + r.assertLog({ substring: true }); + }); });