[Lldb-commits] [lldb] [lldb-dap] Support vscode launch URLs (PR #125843)
Adrian Vogelsgesang via lldb-commits
lldb-commits at lists.llvm.org
Wed Mar 12 05:14:48 PDT 2025
https://github.com/vogelsgesang updated https://github.com/llvm/llvm-project/pull/125843
>From 48e900c6a8bd24c7cbee057eb0d96b9f0b2b4f84 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Wed, 5 Feb 2025 10:11:38 +0000
Subject: [PATCH 1/4] [lldb-dap] Support vscode launch URLs
This commit adds support for starting debug sessions through special
`vscode://llvm-vs-code-extensions.lldb-dap/launch/config?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).
---
lldb/tools/lldb-dap/README.md | 16 +++++++-
lldb/tools/lldb-dap/package.json | 3 +-
lldb/tools/lldb-dap/src-ts/extension.ts | 5 +++
.../lldb-dap/src-ts/uri-launch-handler.ts | 37 +++++++++++++++++++
4 files changed, 59 insertions(+), 2 deletions(-)
create mode 100644 lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
diff --git a/lldb/tools/lldb-dap/README.md b/lldb/tools/lldb-dap/README.md
index 123869a033724..34876c4c37cb6 100644
--- a/lldb/tools/lldb-dap/README.md
+++ b/lldb/tools/lldb-dap/README.md
@@ -174,6 +174,20 @@ 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/launch/config?config={launch-config}`
+URI accepts a [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding)
+JSON launch config.
+
+This is useful, e.g., to integrate with custom scripts which start debugging
+sessions. The URIs might be printed to the terminal, potentially using
+[OSC-8 hyperlinks](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda),
+or passed to `vscode --open-url` or `xdg-open`, although mileage may vary
+depending on your specific debugging setup.
+
### Configuration Settings Reference
For both launch and attach configurations, lldb-dap accepts the following `lldb-dap`
@@ -328,4 +342,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..0a29ddda05713
--- /dev/null
+++ b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
@@ -0,0 +1,37 @@
+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 == '/launch/config') {
+ const configJson = params.get("config");
+ if (configJson === null) {
+ throw new Error("Missing `config` URI parameter");
+ }
+ // Build the debug config
+ let debugConfig: vscode.DebugConfiguration = {
+ type: 'lldb-dap',
+ request: 'launch',
+ name: '',
+ };
+ Object.assign(debugConfig, JSON.parse(configJson));
+ debugConfig.name = debugConfig.name || debugConfig.program || "Adhoc Launch";
+ // 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`);
+ }
+ }
+ }
+}
\ No newline at end of file
>From b315e09158dafea47d106f4fdad0250568a4d295 Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Wed, 5 Feb 2025 19:13:24 +0000
Subject: [PATCH 2/4] Address review comments
---
lldb/tools/lldb-dap/README.md | 4 ++--
lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lldb/tools/lldb-dap/README.md b/lldb/tools/lldb-dap/README.md
index 34876c4c37cb6..4966d5a82c2d7 100644
--- a/lldb/tools/lldb-dap/README.md
+++ b/lldb/tools/lldb-dap/README.md
@@ -182,8 +182,8 @@ The `vscode://llvm-vs-code-extensions.lldb-dap/launch/config?config={launch-conf
URI accepts a [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding)
JSON launch config.
-This is useful, e.g., to integrate with custom scripts which start debugging
-sessions. The URIs might be printed to the terminal, potentially using
+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 `vscode --open-url` or `xdg-open`, although mileage may vary
depending on your specific debugging setup.
diff --git a/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
index 0a29ddda05713..a7f5c3b79fb7b 100644
--- a/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
+++ b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
@@ -9,7 +9,7 @@ export class LaunchUriHandler implements vscode.UriHandler {
if (configJson === null) {
throw new Error("Missing `config` URI parameter");
}
- // Build the debug config
+ // Build the debug config.
let debugConfig: vscode.DebugConfiguration = {
type: 'lldb-dap',
request: 'launch',
>From be0484ce607f4f3d9cb73a7c6c7855c63d5d8bfc Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Tue, 11 Mar 2025 13:02:17 +0000
Subject: [PATCH 3/4] Address more review comments
---
lldb/tools/lldb-dap/README.md | 8 +++++---
lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts | 9 +++++----
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/lldb/tools/lldb-dap/README.md b/lldb/tools/lldb-dap/README.md
index 4966d5a82c2d7..bc732ef7c0695 100644
--- a/lldb/tools/lldb-dap/README.md
+++ b/lldb/tools/lldb-dap/README.md
@@ -178,15 +178,17 @@ The default hostname being used `localhost`.
Debugging sessions can also be starting using special URIs.
-The `vscode://llvm-vs-code-extensions.lldb-dap/launch/config?config={launch-config}`
+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.
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 `vscode --open-url` or `xdg-open`, although mileage may vary
-depending on your specific debugging setup.
+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
diff --git a/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
index a7f5c3b79fb7b..a6e0ad5ce64ee 100644
--- a/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
+++ b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
@@ -4,7 +4,7 @@ export class LaunchUriHandler implements vscode.UriHandler {
async handleUri(uri: vscode.Uri) {
try {
const params = new URLSearchParams(uri.query);
- if (uri.path == '/launch/config') {
+ if (uri.path == '/start') {
const configJson = params.get("config");
if (configJson === null) {
throw new Error("Missing `config` URI parameter");
@@ -16,7 +16,8 @@ export class LaunchUriHandler implements vscode.UriHandler {
name: '',
};
Object.assign(debugConfig, JSON.parse(configJson));
- debugConfig.name = debugConfig.name || debugConfig.program || "Adhoc Launch";
+ 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") {
@@ -30,8 +31,8 @@ export class LaunchUriHandler implements vscode.UriHandler {
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`);
+ await vscode.window.showErrorMessage(`Failed to handle lldb-dap URI request: ${JSON.stringify(err)}`);
}
}
}
-}
\ No newline at end of file
+}
>From a24e9d1d19f69e20ffc95d482e27dad442997b2a Mon Sep 17 00:00:00 2001
From: Adrian Vogelsgesang <avogelsgesang at salesforce.com>
Date: Wed, 12 Mar 2025 11:51:45 +0000
Subject: [PATCH 4/4] Support providing config values as separate arguments
---
lldb/tools/lldb-dap/README.md | 5 +-
.../lldb-dap/src-ts/uri-launch-handler.ts | 52 ++++++++++++++++---
2 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/lldb/tools/lldb-dap/README.md b/lldb/tools/lldb-dap/README.md
index bc732ef7c0695..725e9cf63e02a 100644
--- a/lldb/tools/lldb-dap/README.md
+++ b/lldb/tools/lldb-dap/README.md
@@ -180,7 +180,10 @@ 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.
+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
diff --git a/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
index a6e0ad5ce64ee..0c3b1e9a00d9e 100644
--- a/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
+++ b/lldb/tools/lldb-dap/src-ts/uri-launch-handler.ts
@@ -5,17 +5,57 @@ export class LaunchUriHandler implements vscode.UriHandler {
try {
const params = new URLSearchParams(uri.query);
if (uri.path == '/start') {
- const configJson = params.get("config");
- if (configJson === null) {
- throw new Error("Missing `config` URI parameter");
- }
- // Build the debug config.
+ // Some properties have default values
let debugConfig: vscode.DebugConfiguration = {
type: 'lldb-dap',
request: 'launch',
name: '',
};
- Object.assign(debugConfig, JSON.parse(configJson));
+ // 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.difference` 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
More information about the lldb-commits
mailing list