Skip to content

Commit 3240909

Browse files
authored
feat: adopt supportTerminateDebuggee for browsers and node (#1777)
Fixes #1733 on the way
1 parent 63a641b commit 3240909

File tree

7 files changed

+40
-16
lines changed

7 files changed

+40
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This changelog records changes to stable releases since 1.50.2. "TBA" changes he
55
## Nightly (only)
66

77
- feat: add `Symbol.for("debug.description")` as a way to generate object descriptions ([vscode#102181](https://github.com/microsoft/vscode/issues/102181))
8+
- feat: adopt supportTerminateDebuggee for browsers and node ([#1733](https://github.com/microsoft/vscode-js-debug/issues/1733))
89
- fix: child processes from extension host not getting spawned during debug
910
- fix: support vite HMR source replacements ([#1761](https://github.com/microsoft/vscode-js-debug/issues/1761))
1011
- fix: immediately log stdout/err unless EXT is encountered ([vscode#181785](https://github.com/microsoft/vscode/issues/181785))

src/adapter/debugAdapter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ export class DebugAdapter implements IDisposable {
247247
supportsExceptionOptions: false,
248248
supportsValueFormattingOptions: true,
249249
supportsExceptionInfoRequest: true,
250-
supportTerminateDebuggee: false,
250+
supportTerminateDebuggee: true,
251251
supportsDelayedStackTraceLoading: true,
252252
supportsLoadedSourcesRequest: true,
253253
supportsLogPoints: true,

src/binder.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ export class Binder implements IDisposable {
153153
dap.on('pause', async () => {
154154
return {};
155155
});
156-
dap.on('terminate', () => this._terminateRoot());
157-
dap.on('disconnect', () => this._disconnectRoot());
156+
dap.on('terminate', () => this._terminateRoot(true));
157+
dap.on('disconnect', args => this._disconnectRoot(args));
158158
dap.on('restart', async ({ arguments: params }) => {
159159
await this._restart(params as AnyResolvingConfiguration);
160160
return {};
@@ -195,9 +195,9 @@ export class Binder implements IDisposable {
195195
/**
196196
* Terminates all running targets. Resolves when all have terminated.
197197
*/
198-
private async _terminateRoot() {
198+
private async _terminateRoot(terminateDebuggee?: boolean) {
199199
this._root.state = TargetState.Terminating;
200-
await Promise.all([...this.getLaunchers()].map(l => l.terminate()));
200+
await Promise.all([...this.getLaunchers()].map(l => l.terminate(terminateDebuggee)));
201201
await this._root.waitUntilChildrenAre(TargetState.Terminated);
202202
this._root.state = TargetState.Terminated;
203203
return {};
@@ -206,9 +206,9 @@ export class Binder implements IDisposable {
206206
/**
207207
* Disconnects all running targets. Resolves when all have disconnected.
208208
*/
209-
private async _disconnectRoot() {
209+
private async _disconnectRoot(args: Dap.DisconnectParams) {
210210
if (this._root.state < TargetState.Terminating) {
211-
await this._terminateRoot();
211+
await this._terminateRoot(args.terminateDebuggee);
212212
}
213213

214214
this._rootServices.get<ITelemetryReporter>(ITelemetryReporter).flush();
@@ -516,7 +516,7 @@ export class Binder implements IDisposable {
516516
if (node.value.canStop()) {
517517
node.value.stop();
518518
} else {
519-
this._terminateRoot();
519+
this._terminateRoot(true);
520520
}
521521

522522
await node.waitUntil(TargetState.Terminated);
@@ -533,12 +533,12 @@ export class Binder implements IDisposable {
533533
}
534534

535535
if (node.state < TargetState.Terminating) {
536-
if (args.terminateDebuggee === false && node.value.canDetach()) {
536+
if (args.terminateDebuggee !== true && node.value.canDetach()) {
537537
await node.value.detach();
538538
} else if (node.value.canStop()) {
539539
node.value.stop();
540540
} else {
541-
this._terminateRoot();
541+
this._terminateRoot(args.terminateDebuggee);
542542
}
543543
}
544544

src/targets/node/nodeAttacher.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ import { AnyLaunchConfiguration, INodeAttachConfiguration } from '../../configur
1515
import { retryGetNodeEndpoint } from '../browser/spawn/endpoints';
1616
import { ISourcePathResolverFactory } from '../sourcePathResolverFactory';
1717
import { IStopMetadata } from '../targets';
18+
import { killTree } from './killTree';
1819
import { LeaseFile } from './lease-file';
1920
import { NodeAttacherBase } from './nodeAttacherBase';
2021
import { watchAllChildren } from './nodeAttacherCluster';
2122
import { INodeBinaryProvider, NodeBinary } from './nodeBinaryProvider';
22-
import { IRunData } from './nodeLauncherBase';
23+
import { IProcessTelemetry, IRunData } from './nodeLauncherBase';
2324
import { IProgram, StubProgram, WatchDogProgram } from './program';
2425
import { IRestartPolicy, RestartPolicyFactory } from './restartPolicy';
2526
import { WatchDog } from './watchdogSpawn';
@@ -33,6 +34,8 @@ import { WatchDog } from './watchdogSpawn';
3334
*/
3435
@injectable()
3536
export class NodeAttacher extends NodeAttacherBase<INodeAttachConfiguration> {
37+
private telemetry?: IProcessTelemetry;
38+
3639
constructor(
3740
@inject(INodeBinaryProvider) pathProvider: INodeBinaryProvider,
3841
@inject(ILogger) logger: ILogger,
@@ -136,10 +139,18 @@ export class NodeAttacher extends NodeAttacherBase<INodeAttachConfiguration> {
136139
return doLaunch(this.restarters.create(runData.params.restart));
137140
}
138141

142+
public override async terminate(terminateDebuggee?: boolean): Promise<void> {
143+
await super.terminate();
144+
145+
if (terminateDebuggee && this.telemetry) {
146+
killTree(this.telemetry.processId, this.logger);
147+
}
148+
}
149+
139150
/**
140151
* @override
141152
*/
142-
protected createLifecycle(
153+
protected override createLifecycle(
143154
cdp: Cdp.Api,
144155
run: IRunData<INodeAttachConfiguration>,
145156
target: Cdp.Target.TargetInfo,
@@ -177,12 +188,21 @@ export class NodeAttacher extends NodeAttacherBase<INodeAttachConfiguration> {
177188
const leaseFile = new LeaseFile();
178189
await leaseFile.startTouchLoop();
179190

180-
const binary = await this.resolveNodePath(run.params);
191+
let binary = new NodeBinary('node', undefined);
192+
try {
193+
binary = await this.resolveNodePath(run.params);
194+
} catch {
195+
// ignored -- not really a big deal, just used to find capabilities for
196+
// attach params, but all Node versions post-12 will have the same behavior.
197+
}
198+
181199
const [telemetry] = await Promise.all([
182200
this.gatherTelemetryFromCdp(cdp, run),
183201
this.setEnvironmentVariables(cdp, run, leaseFile.path, parentInfo.targetId, binary),
184202
]);
185203

204+
this.telemetry = telemetry;
205+
186206
if (telemetry && run.params.attachExistingChildren) {
187207
watchAllChildren(
188208
{

src/targets/node/nodeLauncherBase.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ export abstract class NodeLauncherBase<T extends AnyNodeConfiguration> implement
518518
protected async gatherTelemetryFromCdp(
519519
cdp: Cdp.Api,
520520
run: IRunData<T>,
521-
): Promise<IProcessTelemetry | void> {
521+
): Promise<IProcessTelemetry | undefined> {
522522
for (let retries = 0; retries < 8; retries++) {
523523
const telemetry = await cdp.Runtime.evaluate({
524524
contextId: 1,

src/targets/targets.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,11 @@ export interface ILauncher extends IDisposable {
136136

137137
/**
138138
* Terminates the debugged process. This should be idempotent.
139+
* @param terminateDebuggee Whether the debugee should be terminated as well.
140+
* For `launch` type requests, this has no effect, but attach requests should
141+
* use "stop" logic instead of "disconnect" logic when provided.
139142
*/
140-
terminate(): Promise<void>;
143+
terminate(terminateDebuggee?: boolean): Promise<void>;
141144

142145
/**
143146
* Attempts to restart the debugged process. This may no-op for certain

src/test/infra/infra-initialize.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
supportsCondition : true
2626
}
2727
]
28-
supportTerminateDebuggee : false
28+
supportTerminateDebuggee : true
2929
supportedChecksumAlgorithms : [
3030
]
3131
supportsBreakpointLocationsRequest : true

0 commit comments

Comments
 (0)