[Lldb-commits] [lldb] [lldb-dap ext] truncate lldb-dap server restart dialog (PR #181441)
Tom Yang via lldb-commits
lldb-commits at lists.llvm.org
Thu Apr 30 12:59:40 PDT 2026
https://github.com/zhyty updated https://github.com/llvm/llvm-project/pull/181441
>From a13fa1f5c673e9a6bbd45e93638df13ea819c160 Mon Sep 17 00:00:00 2001
From: Tom Yang <toyang at fb.com>
Date: Wed, 11 Feb 2026 11:35:03 -0800
Subject: [PATCH 1/3] [lldb-dap ext] truncate lldb-dap spawn info display
Summary:
Test Plan:
Reviewers:
Subscribers:
Tasks:
Tags:
---
.../lldb-dap/extension/src/lldb-dap-server.ts | 124 +++++++++++++++---
1 file changed, 103 insertions(+), 21 deletions(-)
diff --git a/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts b/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts
index deacdea145a41..05f3b43e808c4 100644
--- a/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts
+++ b/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts
@@ -3,6 +3,77 @@ import * as child_process from "node:child_process";
import { isDeepStrictEqual } from "util";
import * as vscode from "vscode";
+/**
+ * The information needed to spawn a lldb-dap process: e.g. arguments, binary
+ * path, etc.
+ */
+class ServerSpawnInfo {
+ constructor(
+ readonly path: string,
+ readonly args: string[],
+ readonly env: { [key: string]: string },
+ ) {}
+
+ static create(
+ path: string,
+ args: string[],
+ env: NodeJS.ProcessEnv | { [key: string]: string } | undefined,
+ ): ServerSpawnInfo {
+ // Convert env to a plain object for later comparison. We filter out
+ // `LLDBDAP_LOG` because we ignore it when considering reusing lldb-dap
+ // server.
+ const normalizedEnv: { [key: string]: string } = {};
+ for (const [key, value] of Object.entries(env ?? {})) {
+ if (key !== "LLDBDAP_LOG") {
+ normalizedEnv[key] = String(value);
+ }
+ }
+ return new ServerSpawnInfo(path, args, normalizedEnv);
+ }
+
+ /**
+ * Compares this spawn info with another for equality.
+ */
+ equals(other: ServerSpawnInfo): boolean {
+ return isDeepStrictEqual(
+ [this.path, this.args, this.env],
+ [other.path, other.args, other.env],
+ );
+ }
+
+ /**
+ * Returns a human-readable string representation of this spawn info.
+ */
+ toDisplay(): string {
+ const cmd = [this.path, ...this.args];
+
+ const env = Object.entries(this.env)
+ .map(([k, v]) => `${k}=${v}`)
+ // Sort to make it easier to compare. Sorting isn't necessary for the
+ // `isDeepStrictEqual` check.
+ .sort()
+ .join("\n");
+
+ let display = cmd.join(" ");
+ if (env) {
+ display += `\n${env}`;
+ }
+
+ return display;
+ }
+
+ /**
+ * Returns a truncated representation of `toDisplay`.
+ */
+ toDisplayTruncated(maxLength: number = 300): string {
+ const full = this.toDisplay();
+ if (full.length <= maxLength) {
+ return full;
+ }
+ return full.substring(0, maxLength) + "...";
+ }
+}
+
/**
* Represents a running lldb-dap process that is accepting connections (i.e. in "server mode").
*
@@ -12,7 +83,7 @@ import * as vscode from "vscode";
export class LLDBDapServer implements vscode.Disposable {
private serverProcess?: child_process.ChildProcessWithoutNullStreams;
private serverInfo?: Promise<{ host: string; port: number }>;
- private serverSpawnInfo?: string[];
+ private serverSpawnInfo?: ServerSpawnInfo;
// 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.
@@ -87,7 +158,7 @@ export class LLDBDapServer implements vscode.Disposable {
}
});
this.serverProcess = process;
- this.serverSpawnInfo = this.getSpawnInfo(dapPath, dapArgs, options?.env);
+ this.serverSpawnInfo = ServerSpawnInfo.create(dapPath, dapArgs, options?.env);
this.serverFileChanged = false;
this.serverFileWatcher = chokidarWatch(dapPath);
this.serverFileWatcher
@@ -127,17 +198,17 @@ export class LLDBDapServer implements vscode.Disposable {
changeTLDR.push("an old binary");
}
- const newSpawnInfo = this.getSpawnInfo(dapPath, args, env);
- if (!isDeepStrictEqual(this.serverSpawnInfo, newSpawnInfo)) {
+ const newSpawnInfo = ServerSpawnInfo.create(dapPath, args, env);
+ if (!this.serverSpawnInfo.equals(newSpawnInfo)) {
changeTLDR.push("different arguments");
changeDetails.push(`
The previous lldb-dap server was started with:
-${this.serverSpawnInfo.join(" ")}
+${this.serverSpawnInfo.toDisplayTruncated()}
The new lldb-dap server will be started with:
-${newSpawnInfo.join(" ")}
+${newSpawnInfo.toDisplayTruncated()}
`);
}
@@ -157,6 +228,7 @@ Restarting the server will interrupt any existing debug sessions and start a new
},
"Restart",
"Use Existing",
+ "Show Full Details",
);
switch (userInput) {
case "Restart":
@@ -164,6 +236,9 @@ Restarting the server will interrupt any existing debug sessions and start a new
return true;
case "Use Existing":
return true;
+ case "Show Full Details":
+ await this.showFullSpawnInfoComparison(this.serverSpawnInfo, newSpawnInfo);
+ return false;
case undefined:
return false;
}
@@ -191,20 +266,27 @@ Restarting the server will interrupt any existing debug sessions and start a new
}
}
- getSpawnInfo(
- path: string,
- args: string[],
- env: NodeJS.ProcessEnv | { [key: string]: string } | undefined,
- ): string[] {
- return [
- path,
- ...args,
- ...Object.entries(env ?? {})
- // Filter and sort to avoid restarting the server just because the
- // order of env changed or the log path changed.
- .filter((entry) => String(entry[0]) !== "LLDBDAP_LOG")
- .sort()
- .map((entry) => String(entry[0]) + "=" + String(entry[1])),
- ];
+ private async showFullSpawnInfoComparison(
+ oldSpawnInfo: ServerSpawnInfo,
+ newSpawnInfo: ServerSpawnInfo,
+ ): Promise<void> {
+ const content = `Comparing lldb-dap env and args
+===============================
+Each section contains the binary and args on the first line, and then env on the
+following lines.
+
+Existing
+--------
+${oldSpawnInfo.toDisplay()}
+
+New
+--------
+${newSpawnInfo.toDisplay()}
+`;
+ const doc = await vscode.workspace.openTextDocument({
+ content,
+ language: "text",
+ });
+ await vscode.window.showTextDocument(doc, { preview: true });
}
}
>From 6a3bf1eda6656021d8e7b57e3dfd7da6820f30cc Mon Sep 17 00:00:00 2001
From: Tom Yang <toyang at fb.com>
Date: Fri, 13 Feb 2026 15:59:43 -0800
Subject: [PATCH 2/3] join env with space character instead of newline
---
lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts b/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts
index 05f3b43e808c4..b7a59e93e5d9e 100644
--- a/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts
+++ b/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts
@@ -52,7 +52,9 @@ class ServerSpawnInfo {
// Sort to make it easier to compare. Sorting isn't necessary for the
// `isDeepStrictEqual` check.
.sort()
- .join("\n");
+ // Joining with newlines makes it difficult to truncate by string length,
+ // so we opt for space.
+ .join(" ");
let display = cmd.join(" ");
if (env) {
>From 99b9d9d3d289be4b2877f0ebba36f9d1b859705a Mon Sep 17 00:00:00 2001
From: Tom Yang <toyang at meta.com>
Date: Thu, 30 Apr 2026 12:49:28 -0700
Subject: [PATCH 3/3] Remove preview in dialog completely, point users to "Show
Full Details" button
---
.../lldb-dap/extension/src/lldb-dap-server.ts | 28 ++++---------------
1 file changed, 5 insertions(+), 23 deletions(-)
diff --git a/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts b/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts
index b7a59e93e5d9e..14bf0dc07f6cb 100644
--- a/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts
+++ b/lldb/tools/lldb-dap/extension/src/lldb-dap-server.ts
@@ -64,16 +64,6 @@ class ServerSpawnInfo {
return display;
}
- /**
- * Returns a truncated representation of `toDisplay`.
- */
- toDisplayTruncated(maxLength: number = 300): string {
- const full = this.toDisplay();
- if (full.length <= maxLength) {
- return full;
- }
- return full.substring(0, maxLength) + "...";
- }
}
/**
@@ -194,7 +184,6 @@ export class LLDBDapServer implements vscode.Disposable {
}
const changeTLDR = [];
- const changeDetails = [];
if (this.serverFileChanged) {
changeTLDR.push("an old binary");
@@ -202,16 +191,7 @@ export class LLDBDapServer implements vscode.Disposable {
const newSpawnInfo = ServerSpawnInfo.create(dapPath, args, env);
if (!this.serverSpawnInfo.equals(newSpawnInfo)) {
- changeTLDR.push("different arguments");
- changeDetails.push(`
-The previous lldb-dap server was started with:
-
-${this.serverSpawnInfo.toDisplayTruncated()}
-
-The new lldb-dap server will be started with:
-
-${newSpawnInfo.toDisplayTruncated()}
-`);
+ changeTLDR.push("different configuration (args, env)");
}
// If the server hasn't changed, continue startup without killing it.
@@ -225,8 +205,10 @@ ${newSpawnInfo.toDisplayTruncated()}
{
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.`,
+
+Restarting the server will interrupt any existing debug sessions and start a new server.
+
+Click "Show Full Details" to see the differences between the existing and new server configuration.`,
},
"Restart",
"Use Existing",
More information about the lldb-commits
mailing list