llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Roy Shi (royitaqi)

<details>
<summary>Changes</summary>

# 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?".

# 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 
`vscode.workspace.createFileSystemWatcher`).  This patch implements solution 2.

# 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.

&lt;img width="260" height="384" alt="Screenshot 2025-09-19 at 8 40 31 AM" 
src="https://github.com/user-attachments/assets/543947ce-fe30-4850-84a7-28009f7cd3d6";
 /&gt;

Note that the message and detail of the dialog box is different from the 
existing one (which is shown when lldb-dap path/args/env has changed), shown 
below.

&lt;img width="521" height="358" alt="Screenshot 2025-09-19 at 8 42 34 AM" 
src="https://github.com/user-attachments/assets/fa926302-c1e9-45e2-84ad-70fbd16d8dca";
 /&gt;


---
Full diff: https://github.com/llvm/llvm-project/pull/159797.diff


1 Files Affected:

- (modified) lldb/tools/lldb-dap/src-ts/lldb-dap-server.ts (+64-13) 


``````````diff
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 774be50053a17..7a1754f4bce6a 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,5 @@
 import * as child_process from "node:child_process";
+import * as path from "path";
 import { isDeepStrictEqual } from "util";
 import * as vscode from "vscode";
 
@@ -12,6 +13,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?: vscode.FileSystemWatcher;
+  // Indicates whether the lldb-dap executable file has changed since the 
server's startup.
+  private serverFileChanged?: boolean;
 
   constructor() {
     vscode.commands.registerCommand(
@@ -83,6 +88,18 @@ export class LLDBDapServer implements vscode.Disposable {
       });
       this.serverProcess = process;
       this.serverSpawnInfo = this.getSpawnInfo(dapPath, dapArgs, options?.env);
+      this.serverFileChanged = false;
+      // Cannot do `createFileSystemWatcher(dapPath)` for a single file. Have 
to use `RelativePattern`.
+      // See 
https://github.com/microsoft/vscode/issues/141011#issuecomment-1016772527
+      this.serverFileWatcher = vscode.workspace.createFileSystemWatcher(
+        new vscode.RelativePattern(
+          vscode.Uri.file(path.dirname(dapPath)),
+          path.basename(dapPath),
+        ),
+      );
+      this.serverFileWatcher.onDidChange(() => {
+        this.serverFileChanged = true;
+      });
     });
     return this.serverInfo;
   }
@@ -100,20 +117,34 @@ 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;
-    }
+    // Check if the server has changed. If so, generate message and detail for 
user prompt.
+    const messageAndDetail = (() => {
+      if (this.serverFileChanged) {
+        return {
+          message:
+            "The lldb-dap binary has changed. Would you like to restart the 
server?",
+          detail: `An existing lldb-dap server (${this.serverProcess.pid}) is 
running with an old binary.
 
-    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 different arguments.
+Restarting the server will interrupt any existing debug sessions and start a 
new server.`,
+        };
+      }
+
+      const newSpawnInfo = this.getSpawnInfo(dapPath, args, env);
+      if (!isDeepStrictEqual(this.serverSpawnInfo, newSpawnInfo)) {
+        return {
+          message:
+            "The arguments to lldb-dap have changed. Would you like to restart 
the server?",
+          detail: `An existing lldb-dap server (${this.serverProcess.pid}) is 
running with different arguments.
 
 The previous lldb-dap server was started with:
 
@@ -124,15 +155,31 @@ The new lldb-dap server will be started with:
 ${newSpawnInfo.join(" ")}
 
 Restarting the server will interrupt any existing debug sessions and start a 
new server.`,
+        };
+      }
+
+      return null;
+    })();
+
+    // If the server hasn't changed, continue startup without killing it.
+    if (messageAndDetail === null) {
+      return true;
+    }
+
+    // The server has changed. Prompt the user to restart it.
+    const { message, detail } = messageAndDetail;
+    const userInput = await vscode.window.showInformationMessage(
+      message,
+      {
+        modal: true,
+        detail,
       },
       "Restart",
       "Use Existing",
     );
     switch (userInput) {
       case "Restart":
-        this.serverProcess.kill();
-        this.serverProcess = undefined;
-        this.serverInfo = undefined;
+        this.dispose();
         return true;
       case "Use Existing":
         return true;
@@ -156,6 +203,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?.dispose();
+      this.serverFileWatcher = undefined;
+      this.serverFileChanged = undefined;
     }
   }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/159797
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to