diff options
author | royitaqi <royitaqi@users.noreply.github.com> | 2025-08-06 10:24:09 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-06 10:24:09 -0700 |
commit | bb2642fab70fb4d59e431e01e319dcf6b90d88d8 (patch) | |
tree | 416a8edccb739a9779068bcf9b7a6b4dbc633489 | |
parent | b291d02a93bcd24c34cdc0febc327270dc9ceb0c (diff) | |
download | llvm-bb2642fab70fb4d59e431e01e319dcf6b90d88d8.zip llvm-bb2642fab70fb4d59e431e01e319dcf6b90d88d8.tar.gz llvm-bb2642fab70fb4d59e431e01e319dcf6b90d88d8.tar.bz2 |
[vscode-lldb] Fix race condition when changing lldb-dap arguments (#151828)
# Problem
When the user changes lldb-dap's arguments (e.g. path), there is a race
condition, where the new lldb-dap process could be started first and
have set the extension's `serverProcess` and `serverInfo` according to
the new process, while the old lldb-dap process exits later and wipes
out these two fields.
Consequences:
1. This causes `getServerProcess()` to return `undefined` when it should
return the new process.
2. This also causes wrong behavior when starting the next debug session
that a new lldb-dap process will be started and the old not reused nor
killed.
# Fix
When wiping the two fields, check if `serverProcess` equals to the
process captured by the handler. If they equal, wipe the fields. If not,
then the fields have already been updated (either new process has
started, or the fields were already wiped out by another handler), and
so the wiping should be skipped.
-rw-r--r-- | lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts b/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts index 03a0fc9..f360fa3 100644 --- a/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts +++ b/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts @@ -39,8 +39,7 @@ export class LLDBDapServer implements vscode.Disposable { const process = child_process.spawn(dapPath, dapArgs, options); process.on("error", (error) => { reject(error); - this.serverProcess = undefined; - this.serverInfo = undefined; + this.cleanUp(process); }); process.on("exit", (code, signal) => { let errorMessage = "Server process exited early"; @@ -50,8 +49,7 @@ export class LLDBDapServer implements vscode.Disposable { errorMessage += ` due to signal ${signal}`; } reject(new Error(errorMessage)); - this.serverProcess = undefined; - this.serverInfo = undefined; + this.cleanUp(process); }); process.stdout.setEncoding("utf8").on("data", (data) => { const connection = /connection:\/\/\[([^\]]+)\]:(\d+)/.exec( @@ -126,7 +124,16 @@ Restarting the server will interrupt any existing debug sessions and start a new return; } this.serverProcess.kill(); - this.serverProcess = undefined; - this.serverInfo = undefined; + this.cleanUp(this.serverProcess); + } + + cleanUp(process: child_process.ChildProcessWithoutNullStreams) { + // If the following don't equal, then the fields have already been updated + // (either a new process has started, or the fields were already cleaned + // up), and so the cleanup should be skipped. + if (this.serverProcess === process) { + this.serverProcess = undefined; + this.serverInfo = undefined; + } } } |