in src/debugAdapter/goDebug.ts [809:878]
public async close(): Promise<void> {
const forceCleanup = async () => {
log(`killing debugee (pid: ${this.debugProcess?.pid})...`);
if (this.debugProcess) {
await killProcessTree(this.debugProcess, log);
}
if (this.localDebugeePath) {
await removeFile(this.localDebugeePath);
}
};
if (this.noDebug) {
// delve isn't running so no need to halt
await forceCleanup();
return Promise.resolve();
}
const isLocalDebugging: boolean = this.request === 'launch' && !!this.debugProcess;
return new Promise(async (resolve) => {
this.delveConnectionClosed = true;
// For remote debugging, we want to leave the remote dlv server running,
// so instead of killing it via halt+detach, we just close the network connection.
// See https://www.github.com/go-delve/delve/issues/1587
if (this.isRemoteDebugging) {
log('Remote Debugging: close dlv connection.');
const rpcConnection = await this.connection;
// tslint:disable-next-line no-any
(rpcConnection as any)['conn']['end']();
return resolve();
}
const timeoutToken =
isLocalDebugging &&
setTimeout(async () => {
log('Killing debug process manually as we could not halt delve in time');
await forceCleanup();
resolve();
}, 1000);
let haltErrMsg: string | undefined;
try {
log('HaltRequest');
await this.callPromise('Command', [{ name: 'halt' }]);
} catch (err) {
log('HaltResponse');
log(`Failed to halt - ${err}`);
}
if (timeoutToken) {
clearTimeout(timeoutToken);
}
const targetHasExited = !!haltErrMsg && haltErrMsg.endsWith('has exited with status 0');
const shouldDetach = !haltErrMsg || targetHasExited;
let shouldForceClean = !shouldDetach && isLocalDebugging;
if (shouldDetach) {
log('DetachRequest');
try {
await this.callPromise('Detach', [this.isApiV1 ? true : { Kill: isLocalDebugging }]);
} catch (err) {
log('DetachResponse');
logError(`Failed to detach - ${err}`);
shouldForceClean = isLocalDebugging;
}
}
if (shouldForceClean) {
await forceCleanup();
}
return resolve();
});
}