[Lldb-commits] [lldb] 8b9031f - [lldb-dap] Support vscode launch URLs (#125843)

via lldb-commits lldb-commits at lists.llvm.org
Thu Mar 13 15:49:09 PDT 2025


Author: Adrian Vogelsgesang
Date: 2025-03-13T23:49:05+01:00
New Revision: 8b9031f245a268c6acb331de5ea68da20be37051

URL: https://github.com/llvm/llvm-project/commit/8b9031f245a268c6acb331de5ea68da20be37051
DIFF: https://github.com/llvm/llvm-project/commit/8b9031f245a268c6acb331de5ea68da20be37051.diff

LOG: [lldb-dap] Support vscode launch URLs (#125843)

This commit adds support for starting debug sessions through special
`vscode://llvm-vs-code-extensions.lldb-dap/start?config={launch-config}`
URIs. This allows tighter integration with custom scripts. One potential
use case is providing similar functionality to `xcdebug`, see #125777
for some discussion on that use case.

The functionality was inspired by @vadimcn's CodeLLDB extension, which
[provides similar
functionality](https://github.com/vadimcn/codelldb/blob/master/MANUAL.md#debugging-externally-launched-code).

Added: 
    lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts

Modified: 
    lldb/tools/lldb-dap/README.md
    lldb/tools/lldb-dap/package.json
    lldb/tools/lldb-dap/src-ts/extension.ts

Removed: 
    


################################################################################
diff  --git a/lldb/tools/lldb-dap/README.md b/lldb/tools/lldb-dap/README.md
index 123869a033724..725e9cf63e02a 100644
--- a/lldb/tools/lldb-dap/README.md
+++ b/lldb/tools/lldb-dap/README.md
@@ -174,6 +174,25 @@ The default hostname being used `localhost`.
 }
 ```
 
+### Launching via `vscode://` URIs
+
+Debugging sessions can also be starting using special URIs.
+
+The `vscode://llvm-vs-code-extensions.lldb-dap/start?config={launch-config}`
+URI accepts a [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding)
+JSON launch config. The most frequently used arguments (`request`, `program`,
+`args`, `cwd`, `pid`, ...) can also specified directly, e.g.
+`vscode://llvm-vs-code-extensions.lldb-dap/start?request=attach&pid=1234`, or
+`vscode://llvm-vs-code-extensions.lldb-dap/start?program=ls&args=-a&args=/etc`.
+
+This is useful for integration with custom scripts to start debugging
+sessions. The URI might be printed to the terminal, potentially using
+[OSC-8 hyperlinks](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda),
+or passed to `code --open-url` or `xdg-open`, although mileage may vary depending
+on your specific debugging setup. E.g., `code --open-url` will not work when using a
+SSH remote session. Furthermore, placeholders such as `${workspaceFolder}` are not
+supported within launch URLs.
+
 ### Configuration Settings Reference
 
 For both launch and attach configurations, lldb-dap accepts the following `lldb-dap`
@@ -328,4 +347,4 @@ The source code is part of the [LLVM repository](https://github.com/llvm/llvm-pr
 We use Github's [issue tracker](https://github.com/llvm/llvm-project/issues?q=label%3Alldb-dap) and patches can be submitted via [pull requests](https://github.com/llvm/llvm-project/pulls?q=label%3Alldb-dap).
 Furthermore, there is a [LLDB category](https://discourse.llvm.org/c/subprojects/lldb/8) on the LLVM discourse forum.
 
-For instructions on how to get started with development on lldb-dap, see the "[Contributing to lldb-dap](https://lldb.llvm.org/resources/lldbdap.html)"
+For instructions on how to get started with development on lldb-dap, see the "[Contributing to lldb-dap](https://lldb.llvm.org/resources/lldbdap.html)" guide.

diff  --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index cd450a614b3f7..428624f46feba 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -35,7 +35,8 @@
     "typescript": "^5.7.3"
   },
   "activationEvents": [
-    "onDebug"
+    "onDebug",
+    "onUri"
   ],
   "main": "./out/extension",
   "scripts": {

diff  --git a/lldb/tools/lldb-dap/src-ts/extension.ts b/lldb/tools/lldb-dap/src-ts/extension.ts
index a07bcdebcb68b..f0c7fb5bd1a71 100644
--- a/lldb/tools/lldb-dap/src-ts/extension.ts
+++ b/lldb/tools/lldb-dap/src-ts/extension.ts
@@ -5,6 +5,7 @@ import {
   isExecutable,
 } from "./debug-adapter-factory";
 import { DisposableContext } from "./disposable-context";
+import { LaunchUriHandler } from "./uri-launch-handler";
 
 /**
  * This class represents the extension and manages its life cycle. Other extensions
@@ -37,6 +38,10 @@ export class LLDBDapExtension extends DisposableContext {
         }
       }),
     );
+
+    this.pushSubscription(
+      vscode.window.registerUriHandler(new LaunchUriHandler())
+    );
   }
 }
 

diff  --git a/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
new file mode 100644
index 0000000000000..0c3b1e9a00d9e
--- /dev/null
+++ b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
@@ -0,0 +1,78 @@
+import * as vscode from "vscode";
+
+export class LaunchUriHandler implements vscode.UriHandler {
+    async handleUri(uri: vscode.Uri) {
+        try {
+            const params = new URLSearchParams(uri.query);
+            if (uri.path == '/start') {
+                // Some properties have default values
+                let debugConfig: vscode.DebugConfiguration = {
+                    type: 'lldb-dap',
+                    request: 'launch',
+                    name: '',
+                };
+                // The `config` parameter allows providing a complete JSON-encoded configuration
+                const configJson = params.get("config");
+                if (configJson !== null) {
+                    Object.assign(debugConfig, JSON.parse(configJson));
+                }
+                // Furthermore, some frequently used parameters can also be provided as separate parameters
+                const stringKeys = ["name", "request", "program", "cwd", "debuggerRoot"];
+                const numberKeys = ["pid"];
+                const arrayKeys = [
+                    "args", "initCommands", "preRunCommands", "stopCommands", "exitCommands",
+                    "terminateCommands", "launchCommands", "attachCommands"
+                ];
+                for (const key of stringKeys) {
+                    const value = params.get(key);
+                    if (value) {
+                        debugConfig[key] = value;
+                    }
+                }
+                for (const key of numberKeys) {
+                    const value = params.get(key);
+                    if (value) {
+                        debugConfig[key] = Number(value);
+                    }
+                }
+                for (const key of arrayKeys) {
+                    // `getAll()` returns an array of strings.
+                    const value = params.getAll(key);
+                    if (value) {
+                        debugConfig[key] = value;
+                    }
+                }
+                // Report an error if we received any unknown parameters
+                const supportedKeys = new Set<string>(["config"].concat(stringKeys).concat(numberKeys).concat(arrayKeys));
+                const presentKeys = new Set<string>(params.keys());
+                // FIXME: Use `Set.
diff erence` as soon as ES2024 is widely available
+                const unknownKeys = new Set<string>();
+                for (const k of presentKeys.keys()) {
+                    if (!supportedKeys.has(k)) {
+                        unknownKeys.add(k);
+                    }
+                }
+                if (unknownKeys.size > 0) {
+                    throw new Error(`Unsupported URL parameters: ${Array.from(unknownKeys.keys()).join(", ")}`);
+                }
+                // Prodide a default for the config name
+                const defaultName = debugConfig.request == 'launch' ? "URL-based Launch" : "URL-based Attach";
+                debugConfig.name = debugConfig.name || debugConfig.program || defaultName;
+                // Force the type to `lldb-dap`. We don't want to allow launching any other
+                // Debug Adapters using this URI scheme.
+                if (debugConfig.type != "lldb-dap") {
+                    throw new Error(`Unsupported debugger type: ${debugConfig.type}`);
+                }
+                await vscode.debug.startDebugging(undefined, debugConfig);
+            } else {
+                throw new Error(`Unsupported Uri path: ${uri.path}`);
+            }
+        } catch (err) {
+            if (err instanceof Error) {
+                await vscode.window.showErrorMessage(`Failed to handle lldb-dap URI request: ${err.message}`);
+            } else {
+                await vscode.window.showErrorMessage(`Failed to handle lldb-dap URI request: ${JSON.stringify(err)}`);
+            }
+        }
+    }
+}


        


More information about the lldb-commits mailing list