[llvm-branch-commits] [lldb] 6007a4d - [vscode-lldb] Restart server when lldb-dap binary has changed (#159797)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Sep 23 08:57:54 PDT 2025
Author: Roy Shi
Date: 2025-09-23T07:44:50-07:00
New Revision: 6007a4dbed2d8867c75bd571e1eb38e10ae14a27
URL: https://github.com/llvm/llvm-project/commit/6007a4dbed2d8867c75bd571e1eb38e10ae14a27
DIFF: https://github.com/llvm/llvm-project/commit/6007a4dbed2d8867c75bd571e1eb38e10ae14a27.diff
LOG: [vscode-lldb] Restart server when lldb-dap binary has changed (#159797)
# Motiviation
This helps the development of the lldb-dap binary. For example, when
testing a locally built lldb-dap binary, one probably wants to restart
the server after each build in order to use the latest binary. Not doing
so leads to confusion like "why the new lldb-dap isn't doing what I just
changed?".
This patch adds dependency to the `chokidar` package. The reason is that
we need something to detect changes to the `lldb-dap` binary file and
`chokidar` appears to be the most reliable package to do so. An
alternative solution which doesn't require adding dependencies is
discussed below (solution 1).
# Two different solutions considered
Solution 1: Restart server when lldb-dap binary's modification time
changes. https://github.com/llvm/llvm-project/pull/159481 implements
solution 1.
Solution 2: Restart server when lldb-dap binary has changed (as detected
by a file system watcher). This patch implements solution 2 (using
`chokidar`).
# This patch (solution 2)
If the lldb-dap binary has changed, the next time the user start a debug
session, a dialog box will show up and prompt the user to restart the
server. Depend on what has changed, the dialog box will show different
content (see below)
* When both the lldb-dap binary and the arguments have changed:
<img width="520" height="357" alt="diff_args_and_binary"
src="https://github.com/user-attachments/assets/6580e05f-05c3-4d80-8c1a-9c3abf279218"
/>
* When only the lldb-dap binary has changed:
<img width="260" height="384" alt="diff_binary"
src="https://github.com/user-attachments/assets/933b8987-9c21-44f3-ad68-57b8eeb58525"
/>
* When only the arguments have changed (existing):
<img width="520" height="343" alt="diff_args"
src="https://github.com/user-attachments/assets/c0e6771c-ad32-4fb8-b5df-b34cce48ed1a"
/>
Added:
Modified:
lldb/tools/lldb-dap/package-lock.json
lldb/tools/lldb-dap/package.json
lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts
Removed:
################################################################################
diff --git a/lldb/tools/lldb-dap/package-lock.json b/lldb/tools/lldb-dap/package-lock.json
index f3ae6b76be6d0..826f29f70106c 100644
--- a/lldb/tools/lldb-dap/package-lock.json
+++ b/lldb/tools/lldb-dap/package-lock.json
@@ -8,6 +8,9 @@
"name": "lldb-dap",
"version": "0.2.16",
"license": "Apache 2.0 License with LLVM exceptions",
+ "dependencies": {
+ "chokidar": "^4.0.3"
+ },
"devDependencies": {
"@types/node": "^18.19.41",
"@types/tabulator-tables": "^6.2.10",
@@ -1301,6 +1304,21 @@
"url": "https://github.com/sponsors/fb55"
}
},
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
@@ -2746,6 +2764,19 @@
"node": ">= 6"
}
},
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index 6566ba3bdee13..3892535853f56 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -27,6 +27,9 @@
"categories": [
"Debuggers"
],
+ "dependencies": {
+ "chokidar": "^4.0.3"
+ },
"devDependencies": {
"@types/node": "^18.19.41",
"@types/tabulator-tables": "^6.2.10",
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 280a11d807f6a..4e348965930d9 100644
--- a/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts
+++ b/lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts
@@ -1,4 +1,6 @@
+import { FSWatcher, watch as chokidarWatch } from 'chokidar';
import * as child_process from "node:child_process";
+import * as path from "path";
import { isDeepStrictEqual } from "util";
import * as vscode from "vscode";
@@ -12,6 +14,10 @@ export class LLDBDapServer implements vscode.Disposable {
private serverProcess?: child_process.ChildProcessWithoutNullStreams;
private serverInfo?: Promise<{ host: string; port: number }>;
private serverSpawnInfo?: string[];
+ // Detects changes to the lldb-dap executable file since the server's startup.
+ private serverFileWatcher?: FSWatcher;
+ // Indicates whether the lldb-dap executable file has changed since the server's startup.
+ private serverFileChanged?: boolean;
constructor() {
vscode.commands.registerCommand(
@@ -83,6 +89,11 @@ export class LLDBDapServer implements vscode.Disposable {
});
this.serverProcess = process;
this.serverSpawnInfo = this.getSpawnInfo(dapPath, dapArgs, options?.env);
+ this.serverFileChanged = false;
+ this.serverFileWatcher = chokidarWatch(dapPath);
+ this.serverFileWatcher
+ .on('change', () => this.serverFileChanged = true)
+ .on('unlink', () => this.serverFileChanged = true);
});
return this.serverInfo;
}
@@ -100,21 +111,27 @@ export class LLDBDapServer implements vscode.Disposable {
args: string[],
env: NodeJS.ProcessEnv | { [key: string]: string } | undefined,
): Promise<boolean> {
- if (!this.serverProcess || !this.serverInfo || !this.serverSpawnInfo) {
+ if (
+ !this.serverProcess ||
+ !this.serverInfo ||
+ !this.serverSpawnInfo ||
+ !this.serverFileWatcher ||
+ this.serverFileChanged === undefined
+ ) {
return true;
}
- const newSpawnInfo = this.getSpawnInfo(dapPath, args, env);
- if (isDeepStrictEqual(this.serverSpawnInfo, newSpawnInfo)) {
- return true;
- }
+ const changeTLDR = [];
+ const changeDetails = [];
- const userInput = await vscode.window.showInformationMessage(
- "The arguments to lldb-dap have changed. Would you like to restart the server?",
- {
- modal: true,
- detail: `An existing lldb-dap server (${this.serverProcess.pid}) is running with
diff erent arguments.
+ if (this.serverFileChanged) {
+ changeTLDR.push("an old binary");
+ }
+ const newSpawnInfo = this.getSpawnInfo(dapPath, args, env);
+ if (!isDeepStrictEqual(this.serverSpawnInfo, newSpawnInfo)) {
+ changeTLDR.push("
diff erent arguments");
+ changeDetails.push(`
The previous lldb-dap server was started with:
${this.serverSpawnInfo.join(" ")}
@@ -122,7 +139,22 @@ ${this.serverSpawnInfo.join(" ")}
The new lldb-dap server will be started with:
${newSpawnInfo.join(" ")}
+`
+ );
+ }
+
+ // If the server hasn't changed, continue startup without killing it.
+ if (changeTLDR.length === 0) {
+ return true;
+ }
+ // The server has changed. Prompt the user to restart it.
+ const userInput = await vscode.window.showInformationMessage(
+ "The lldb-dap server has changed. Would you like to restart the server?",
+ {
+ modal: true,
+ detail: `An existing lldb-dap server (${this.serverProcess.pid}) is running with ${changeTLDR.map(s => `*${s}*`).join(" and ")}.
+${changeDetails.join("\n")}
Restarting the server will interrupt any existing debug sessions and start a new server.`,
},
"Restart",
@@ -130,9 +162,7 @@ Restarting the server will interrupt any existing debug sessions and start a new
);
switch (userInput) {
case "Restart":
- this.serverProcess.kill();
- this.serverProcess = undefined;
- this.serverInfo = undefined;
+ this.dispose();
return true;
case "Use Existing":
return true;
@@ -156,6 +186,10 @@ Restarting the server will interrupt any existing debug sessions and start a new
if (this.serverProcess === process) {
this.serverProcess = undefined;
this.serverInfo = undefined;
+ this.serverSpawnInfo = undefined;
+ this.serverFileWatcher?.close();
+ this.serverFileWatcher = undefined;
+ this.serverFileChanged = undefined;
}
}
More information about the llvm-branch-commits
mailing list