Skip to content

Commit cbb1086

Browse files
authored
fix: race in entrypoint breakpoints (#1360)
* fix: race in entrypoint breakpoints This was causing a ~10% failure in a test, and could have caused some failures for users in edge cases (where rarely stepping into the first function or class declaration in a file would not work.) * chore: update vscode-test for resiliency, use newer macos image * chore: use node 16 in CI to match vscode
1 parent 1d9149e commit cbb1086

File tree

6 files changed

+56
-55
lines changed

6 files changed

+56
-55
lines changed

.ci/pipeline.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,27 @@ jobs:
66
- job: macOS
77
timeoutInMinutes: 20
88
pool:
9-
vmImage: 'macOS-10.15'
9+
vmImage: 'macos-latest'
1010
steps:
1111
- template: common-validation.yml
1212
variables:
13-
node_version: 14.18.3
13+
node_version: 16.14.2
1414

1515
- job: Linux
1616
pool:
1717
vmImage: 'ubuntu-18.04'
1818
steps:
1919
- template: common-validation.yml
2020
variables:
21-
node_version: 14.18.3
21+
node_version: 16.14.2
2222

2323
- job: LinuxMinspec
2424
pool:
2525
vmImage: 'ubuntu-18.04'
2626
steps:
2727
- template: common-validation.yml
2828
variables:
29-
node_version: 14.18.3
29+
node_version: 16.14.2
3030
only_minspec: true
3131

3232
- job: Windows
@@ -35,4 +35,4 @@ jobs:
3535
steps:
3636
- template: common-validation.yml
3737
variables:
38-
node_version: 14.18.3
38+
node_version: 16.14.2

package-lock.json

Lines changed: 18 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@
122122
"@types/ws": "^8.5.3",
123123
"@typescript-eslint/eslint-plugin": "^5.17.0",
124124
"@typescript-eslint/parser": "^5.17.0",
125-
"@vscode/test-electron": "^2.1.3",
125+
"@vscode/test-electron": "^2.1.5",
126126
"chai": "^4.3.6",
127127
"chai-as-promised": "^7.1.1",
128128
"chai-string": "^1.5.0",

src/adapter/breakpoints/breakpointBase.ts

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,13 @@ export abstract class Breakpoint {
217217
cdpId: Cdp.Debugger.BreakpointId,
218218
resolvedLocations: readonly Cdp.Debugger.Location[],
219219
) {
220+
// Update with the resolved locations immediately and synchronously. This
221+
// prevents a race conditions where a source is parsed immediately before
222+
// a breakpoint it hit and not returning correctly in `BreakpointManager.isEntrypointBreak`.
223+
// This _can_ be fairly prevelant, especially when resolving UI locations
224+
// involves loading or waiting for source maps.
225+
this.updateExistingCdpRef(cdpId, bp => ({ ...bp, locations: resolvedLocations }));
226+
220227
const uiLocation = (
221228
await Promise.all(
222229
resolvedLocations.map(l => thread.rawLocationToUiLocation(thread.rawLocation(l))),
@@ -232,20 +239,15 @@ export abstract class Breakpoint {
232239
return;
233240
}
234241

235-
this.updateCdpRefs(list =>
236-
list.map(bp => {
237-
if (bp.state !== CdpReferenceState.Applied || bp.cdpId !== cdpId) {
238-
return bp;
239-
}
240-
const locations = this._manager._sourceContainer.currentSiblingUiLocations(uiLocation);
241-
const inPreferredSource = locations.filter(l => l.source === source);
242-
return {
243-
...bp,
244-
locations: resolvedLocations,
245-
uiLocations: inPreferredSource.length ? inPreferredSource : locations,
246-
};
247-
}),
248-
);
242+
this.updateExistingCdpRef(cdpId, bp => {
243+
const locations = this._manager._sourceContainer.currentSiblingUiLocations(uiLocation);
244+
const inPreferredSource = locations.filter(l => l.source === source);
245+
return {
246+
...bp,
247+
locations: resolvedLocations,
248+
uiLocations: inPreferredSource.length ? inPreferredSource : locations,
249+
};
250+
});
249251
}
250252

251253
/**
@@ -377,6 +379,20 @@ export abstract class Breakpoint {
377379
return undefined;
378380
}
379381

382+
/**
383+
* Updates an existing applied CDP breakpoint, by its CDP ID.
384+
*/
385+
protected updateExistingCdpRef(
386+
cdpId: string,
387+
mutator: (l: Readonly<BreakpointCdpReference>) => Readonly<BreakpointCdpReference>,
388+
) {
389+
this.updateCdpRefs(list =>
390+
list.map(bp =>
391+
bp.state !== CdpReferenceState.Applied || bp.cdpId !== cdpId ? bp : mutator(bp),
392+
),
393+
);
394+
}
395+
380396
/**
381397
* Updates the list of CDP breakpoint references. Used to provide lifecycle
382398
* hooks to consumers and internal caches.

src/test/node/node-runtime-sets-arguments.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
0: '--some'
99
1: 'very fancy'
1010
2: '--arguments'
11-
> __proto__: Array(0)
12-
> __proto__: Object
1311
length: 3
12+
> [[Prototype]]: Array(0)
13+
> [[Prototype]]: Object

src/test/node/node-runtime.test.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -497,10 +497,6 @@ describe('node runtime', () => {
497497
});
498498

499499
itIntegrates('sets arguments', async ({ r }) => {
500-
if (process.platform === 'darwin') {
501-
return; // the ADO runner on Darwin seems to use the wrong Node version
502-
}
503-
504500
createFileTree(testFixturesDir, { 'test.js': 'debugger' });
505501
const handle = await r.runScript('test.js', {
506502
args: ['--some', 'very fancy', '--arguments'],

0 commit comments

Comments
 (0)