Skip to content

Commit 0ee103c

Browse files
vogelsgesangfrederik-h
authored andcommitted
[lldb-dap] Support vscode launch URLs (llvm#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 llvm#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).
1 parent 6dafd13 commit 0ee103c

File tree

4 files changed

+105
-2
lines changed

4 files changed

+105
-2
lines changed

lldb/tools/lldb-dap/README.md

+20-1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,25 @@ The default hostname being used `localhost`.
174174
}
175175
```
176176

177+
### Launching via `vscode://` URIs
178+
179+
Debugging sessions can also be starting using special URIs.
180+
181+
The `vscode://llvm-vs-code-extensions.lldb-dap/start?config={launch-config}`
182+
URI accepts a [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding)
183+
JSON launch config. The most frequently used arguments (`request`, `program`,
184+
`args`, `cwd`, `pid`, ...) can also specified directly, e.g.
185+
`vscode://llvm-vs-code-extensions.lldb-dap/start?request=attach&pid=1234`, or
186+
`vscode://llvm-vs-code-extensions.lldb-dap/start?program=ls&args=-a&args=/etc`.
187+
188+
This is useful for integration with custom scripts to start debugging
189+
sessions. The URI might be printed to the terminal, potentially using
190+
[OSC-8 hyperlinks](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda),
191+
or passed to `code --open-url` or `xdg-open`, although mileage may vary depending
192+
on your specific debugging setup. E.g., `code --open-url` will not work when using a
193+
SSH remote session. Furthermore, placeholders such as `${workspaceFolder}` are not
194+
supported within launch URLs.
195+
177196
### Configuration Settings Reference
178197

179198
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
328347
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).
329348
Furthermore, there is a [LLDB category](https://discourse.llvm.org/c/subprojects/lldb/8) on the LLVM discourse forum.
330349

331-
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)"
350+
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.

lldb/tools/lldb-dap/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
"typescript": "^5.7.3"
3636
},
3737
"activationEvents": [
38-
"onDebug"
38+
"onDebug",
39+
"onUri"
3940
],
4041
"main": "./out/extension",
4142
"scripts": {

lldb/tools/lldb-dap/src-ts/extension.ts

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
isExecutable,
66
} from "./debug-adapter-factory";
77
import { DisposableContext } from "./disposable-context";
8+
import { LaunchUriHandler } from "./uri-launch-handler";
89

910
/**
1011
* This class represents the extension and manages its life cycle. Other extensions
@@ -37,6 +38,10 @@ export class LLDBDapExtension extends DisposableContext {
3738
}
3839
}),
3940
);
41+
42+
this.pushSubscription(
43+
vscode.window.registerUriHandler(new LaunchUriHandler())
44+
);
4045
}
4146
}
4247

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import * as vscode from "vscode";
2+
3+
export class LaunchUriHandler implements vscode.UriHandler {
4+
async handleUri(uri: vscode.Uri) {
5+
try {
6+
const params = new URLSearchParams(uri.query);
7+
if (uri.path == '/start') {
8+
// Some properties have default values
9+
let debugConfig: vscode.DebugConfiguration = {
10+
type: 'lldb-dap',
11+
request: 'launch',
12+
name: '',
13+
};
14+
// The `config` parameter allows providing a complete JSON-encoded configuration
15+
const configJson = params.get("config");
16+
if (configJson !== null) {
17+
Object.assign(debugConfig, JSON.parse(configJson));
18+
}
19+
// Furthermore, some frequently used parameters can also be provided as separate parameters
20+
const stringKeys = ["name", "request", "program", "cwd", "debuggerRoot"];
21+
const numberKeys = ["pid"];
22+
const arrayKeys = [
23+
"args", "initCommands", "preRunCommands", "stopCommands", "exitCommands",
24+
"terminateCommands", "launchCommands", "attachCommands"
25+
];
26+
for (const key of stringKeys) {
27+
const value = params.get(key);
28+
if (value) {
29+
debugConfig[key] = value;
30+
}
31+
}
32+
for (const key of numberKeys) {
33+
const value = params.get(key);
34+
if (value) {
35+
debugConfig[key] = Number(value);
36+
}
37+
}
38+
for (const key of arrayKeys) {
39+
// `getAll()` returns an array of strings.
40+
const value = params.getAll(key);
41+
if (value) {
42+
debugConfig[key] = value;
43+
}
44+
}
45+
// Report an error if we received any unknown parameters
46+
const supportedKeys = new Set<string>(["config"].concat(stringKeys).concat(numberKeys).concat(arrayKeys));
47+
const presentKeys = new Set<string>(params.keys());
48+
// FIXME: Use `Set.difference` as soon as ES2024 is widely available
49+
const unknownKeys = new Set<string>();
50+
for (const k of presentKeys.keys()) {
51+
if (!supportedKeys.has(k)) {
52+
unknownKeys.add(k);
53+
}
54+
}
55+
if (unknownKeys.size > 0) {
56+
throw new Error(`Unsupported URL parameters: ${Array.from(unknownKeys.keys()).join(", ")}`);
57+
}
58+
// Prodide a default for the config name
59+
const defaultName = debugConfig.request == 'launch' ? "URL-based Launch" : "URL-based Attach";
60+
debugConfig.name = debugConfig.name || debugConfig.program || defaultName;
61+
// Force the type to `lldb-dap`. We don't want to allow launching any other
62+
// Debug Adapters using this URI scheme.
63+
if (debugConfig.type != "lldb-dap") {
64+
throw new Error(`Unsupported debugger type: ${debugConfig.type}`);
65+
}
66+
await vscode.debug.startDebugging(undefined, debugConfig);
67+
} else {
68+
throw new Error(`Unsupported Uri path: ${uri.path}`);
69+
}
70+
} catch (err) {
71+
if (err instanceof Error) {
72+
await vscode.window.showErrorMessage(`Failed to handle lldb-dap URI request: ${err.message}`);
73+
} else {
74+
await vscode.window.showErrorMessage(`Failed to handle lldb-dap URI request: ${JSON.stringify(err)}`);
75+
}
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)