Skip to content

Support LLDB-DAP as a debugger (OSX/Linux/Windows) #13569

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 31 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e9b2659
Enable using LLDB-DAP to debug
fearthecowboy Apr 29, 2025
22439cc
Merge branch 'main' of https://github.com/microsoft/vscode-cpptools i…
fearthecowboy Apr 29, 2025
e2d7deb
Fix test
fearthecowboy Apr 29, 2025
ba4d413
Merge branch 'main' into dev/garretts/implement-lldb-dap
fearthecowboy Apr 29, 2025
9313999
fix cppvsdbg console type when generating config
fearthecowboy Apr 29, 2025
a433293
Merge branch 'dev/garretts/implement-lldb-dap' of https://github.com/…
fearthecowboy Apr 29, 2025
30b5be6
Address feedback
fearthecowboy Apr 30, 2025
c983a01
Merge branch 'main' into dev/garretts/implement-lldb-dap
fearthecowboy May 1, 2025
5e17eee
address feedback
fearthecowboy May 2, 2025
94f0586
Merge branch 'dev/garretts/implement-lldb-dap' of https://github.com/…
fearthecowboy May 2, 2025
0aa3fc8
Merge branch 'main' of https://github.com/microsoft/vscode-cpptools i…
fearthecowboy May 2, 2025
b603db6
Merge branch 'main' into dev/garretts/implement-lldb-dap
sean-mcmanus May 5, 2025
54bfc00
Latest update from @fearthecowboy. Still need to review lint issues.
bobbrow May 16, 2025
c48a4fb
Merge branch 'main' into dev/garretts/implement-lldb-dap
sean-mcmanus May 19, 2025
f487c9b
Fix build errors.
sean-mcmanus May 19, 2025
58f5ae3
Fix linter errors.
sean-mcmanus May 19, 2025
0e2ddc6
Move the imports.
sean-mcmanus May 20, 2025
9a3da2b
Alternative fix for linter errors.
sean-mcmanus May 20, 2025
9f99738
Merge branch 'main' into dev/garretts/implement-lldb-dap
sean-mcmanus May 20, 2025
c5899fa
Merge branch 'main' into dev/garretts/implement-lldb-dap
sean-mcmanus May 27, 2025
803e8a9
Fix string issues.
sean-mcmanus May 29, 2025
10563fa
Merge branch 'main' into dev/garretts/implement-lldb-dap
sean-mcmanus May 29, 2025
d225eeb
Fix stopAtEntry, sourceFileMap, processId.
sean-mcmanus May 29, 2025
6532902
Merge branch 'main' into dev/garretts/implement-lldb-dap
sean-mcmanus May 29, 2025
01cfad9
Fix some comments.
sean-mcmanus May 29, 2025
e7c7ccd
Fix /path/to/gdb not being localized.
sean-mcmanus May 29, 2025
23f4d67
Remove "ada" from the vsdbg and cpplldb langauge lists.
sean-mcmanus May 30, 2025
998b257
Fix `; if (`
sean-mcmanus Jun 2, 2025
18a108a
Fix comment/string casing issues.
sean-mcmanus Jun 2, 2025
acaa8d1
Missed some cases.
sean-mcmanus Jun 2, 2025
8309a02
More comment fixes, mostly with /* blocks.
sean-mcmanus Jun 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Extension/.scripts/generateOptionsSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ export async function main() {
packageJSON.contributes.debuggers[1].configurationAttributes.launch = schemaJSON.definitions.CppvsdbgLaunchOptions;
packageJSON.contributes.debuggers[1].configurationAttributes.attach = schemaJSON.definitions.CppvsdbgAttachOptions;

// cpplldb
packageJSON.contributes.debuggers[2].configurationAttributes.launch = schemaJSON.definitions.CpplldbLaunchOptions;
packageJSON.contributes.debuggers[2].configurationAttributes.attach = schemaJSON.definitions.CpplldbAttachOptions;

let content: string = JSON.stringify(packageJSON, null, 4);

// We use '\u200b' (unicode zero-length space character) to break VS Code's URL detection regex for URLs that are examples. This process will
Expand Down
1,427 changes: 1,412 additions & 15 deletions Extension/package.json

Large diffs are not rendered by default.

63 changes: 63 additions & 0 deletions Extension/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,69 @@
"c_cpp.debuggers.vsCodeCommand.description": "VS Code command to be invoked. Can be a command in VS Code or an active extension.",
"c_cpp.debuggers.vsCodeCommand.command.description": "VS Code command to be invoked.",
"c_cpp.debuggers.vsCodeCommand.args.description": "Arguments to the VS Code command.",
"c_cpp.debuggers.cpplldb.debuggerPath.description": {
"message": "Full path to the LLDB-DAP debugger executable. If not specified, the extension will search for the debugger in the system PATH.",
"comment": [
"{Locked=\"LLDB-DAP\"} {Locked=\"PATH\"}"
]
},
"c_cpp.debuggers.cpplldb.debuggerArgs.description": {
"message": "Additional arguments for the LLDB-DAP debugger.",
"comment": [
"{Locked=\"LLDB-DAP\"}"
]
},
"c_cpp.debuggers.cpplldb.externalConsole.description": "If true, launch the external console for the debugger.",
"c_cpp.debuggers.cpplldb.disableAslr.description": "Disable Address Space Layout Randomization (if supported).",
"c_cpp.debuggers.cpplldb.disableStdio.description": "Disables the standard input/output streams during debugging.",
"c_cpp.debuggers.cpplldb.expandShellArguments.description": "Expands program arguments as a shell would (does not actually launch the program in a shell).",
"c_cpp.debuggers.cpplldb.detachOnError.description": "Detach the debugger when an error occurs.",
"c_cpp.debuggers.cpplldb.debuggerRoot.description": "The directory where relative object files can be located.",
"c_cpp.debuggers.cpplldb.targetTriple.description": "Overrides the target triple of the target program.",
"c_cpp.debuggers.cpplldb.platformName.description": "Overrides the platform name of the target program.",
"c_cpp.debuggers.cpplldb.initCommands.description": "LLDB commands executed upon debugger startup prior to creating the LLDB target.",
"c_cpp.debuggers.cpplldb.preRunCommands.description": "LLDB commands executed just before launching/attaching, after the LLDB target has been created.",
"c_cpp.debuggers.cpplldb.postRunCommands.description": "LLDB commands executed after launching when it's in a stopped state prior to any automatic continuation.",
"c_cpp.debuggers.cpplldb.launchCommands.description": "Custom LLDB commands that are executed instead of launching a process.",
"c_cpp.debuggers.cpplldb.stopCommands.description": "LLDB commands executed each time the program stops.",
"c_cpp.debuggers.cpplldb.exitCommands.description": "LLDB commands executed when the program exits.",
"c_cpp.debuggers.cpplldb.terminateCommands.description": "LLDB commands executed when the debugging session ends.",
"c_cpp.debuggers.cpplldb.enableAutoVariableSummaries.description": "Enable auto-generated summaries for variables when no summaries exist for a given type. This feature can cause performance delays in large projects when viewing variables.",
"c_cpp.debuggers.cpplldb.displayExtendedBacktrace.description": "Enable language-specific extended backtraces.",
"c_cpp.debuggers.cpplldb.enableSyntheticChildDebugging.description": "If a variable is displayed using synthetic children, also display the actual contents of the variable at the end under an entry. This is useful when creating synthetic child plug-ins as it lets you see the actual contents of the variable.",
"c_cpp.debuggers.cpplldb.commandEscapePrefix.description": "The escape prefix character to use for executing regular LLDB commands in the Debug Console, instead of printing variables.",
"c_cpp.debuggers.cpplldb.customFrameFormat.markdownDescription": {
"message": "When specified, stack frames will have descriptions generated based on the provided format. See https://lldb.llvm.org/use/formatting.html.",
"comment": [
"{Locked=\"https://lldb.llvm.org/use/formatting.html\"}"
]
},
"c_cpp.debuggers.cpplldb.customThreadFormat.markdownDescription": {
"message": "When specified, threads will have descriptions generated based on the provided format. See https://lldb.llvm.org/use/formatting.html.",
"comment": [
"{Locked=\"https://lldb.llvm.org/use/formatting.html\"}"
]
},
"c_cpp.debuggers.cpplldb.attachCommands.description": "Custom LLDB commands that are executed instead of attaching to a process ID or to a process by name.",
"c_cpp.debuggers.cpplldb.waitFor.markdownDescription": {
"message": "Wait for the process to launch by looking for a process with a basename that matches the value specified in `program`.",
"comment": [
"{Locked=\"`program`\"}"
]
},
"c_cpp.debuggers.cpplldb.coreFile.description": "Path to the core file to debug.",
"c_cpp.debuggers.cpplldb.gdbRemotePort.markdownDescription": {
"message": "TCP/IP port to attach to a remote system. Specifying both `processId` and `port` is an error.",
"comment": [
"{Locked=\"`processId`\"} {Locked=\"`port`\"}"
]
},
"c_cpp.debuggers.cpplldb.gdbRemoteHost.markdownDescription": {
"message": "The hostname to connect to a remote system. The default hostname is `localhost`.",
"comment": [
"{Locked=\"`localhost`\"}"
]
},
"c_cpp.taskDefinitions.name.description": "The name of the task.",
"c_cpp.taskDefinitions.command.description": "The path to either a compiler or script that performs compilation.",
"c_cpp.taskDefinitions.args.description": "Additional arguments to pass to the compiler or compilation script.",
Expand Down
4 changes: 4 additions & 0 deletions Extension/src/Debugger/attachQuickPick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class RefreshButton implements vscode.QuickInputButton {

export interface AttachItem extends vscode.QuickPickItem {
id?: string;
name?: string;
pid?: string;
commandLine?: string;
fullPath?: string;
}

// We should not await on this function.
Expand Down
47 changes: 43 additions & 4 deletions Extension/src/Debugger/attachToProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import * as path from 'path';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import * as util from '../common';
import { executableName, ProcessReturnType, spawnChildProcess } from '../common-remote-safe';
import * as debugUtils from './utils';

nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
Expand All @@ -21,13 +22,52 @@ export interface AttachItemsProvider {
getAttachItems(token?: vscode.CancellationToken): Promise<AttachItem[]>;
}

/**
* Determines if a process matches the specified filter criteria.
*
* This function checks if the given process name or its full path matches
* the provided filter string. It also normalizes the filter string to handle
* relative paths and compares the executable name derived from the filter
* with the executable name of the process.
*
* @param filterTo - The filter string to match against. This can be a process name,
* an executable name, or a file path.
* @param processName - The name of the process to check.
* @param fullPath - The full path of the process executable, if available.
* @returns `true` if the process matches the filter criteria; otherwise, `false`.
*/
export function processMatches(filterTo: string, processName: string, fullPath: string | undefined) {
const normalized = path.resolve(filterTo);
const executable = executableName(filterTo);

// Filter out the processes that do not somehow match.
return processName === filterTo || executableName(processName) === executable || fullPath === filterTo || fullPath === normalized;
}

export class AttachPicker {
constructor(private attachItemsProvider: AttachItemsProvider) { }

// We should not await on this function.
public async ShowAttachEntries(token?: vscode.CancellationToken): Promise<string | undefined> {
return showQuickPick(() => this.attachItemsProvider.getAttachItems(token));
}

/** Shows the Attach QuickPick, but if a valid filterTo process name/path is passed in, it only shows those entries. */
public async ShowAttachEntriesFiltered(filterTo?: string, token?: vscode.CancellationToken): Promise<string | undefined> {
return showQuickPick(async () => {

const items = await this.attachItemsProvider.getAttachItems(token);
if (filterTo) {
// Filter out the processes that do not somehow match.
const filtered = items.filter(each => processMatches(filterTo, each.label, each.fullPath));
if (filtered.length > 0) {
// Only filter the list if we have actual matches.
return filtered;
}
}
return items;
});
}
}

export class RemoteAttachPicker {
Expand Down Expand Up @@ -177,18 +217,17 @@ export class RemoteAttachPicker {
return 0;
}
return aLower < bLower ? -1 : 1;
})
.map(p => p.toAttachItem());
});
}
}
}

private async getRemoteProcessesExtendedRemote(miDebuggerPath: string, miDebuggerServerAddress: string): Promise<AttachItem[]> {
const args: string[] = [`-ex "target extended-remote ${miDebuggerServerAddress}"`, '-ex "info os processes"', '-batch'];
let processListOutput: util.ProcessReturnType = await util.spawnChildProcess(miDebuggerPath, args);
let processListOutput: ProcessReturnType = await spawnChildProcess(miDebuggerPath, args);
// The device may not be responsive for a while during the restart after image deploy. Retry 5 times.
for (let i: number = 0; i < 5 && !processListOutput.succeeded && processListOutput.outputError.length === 0; i++) {
processListOutput = await util.spawnChildProcess(miDebuggerPath, args);
processListOutput = await spawnChildProcess(miDebuggerPath, args);
}

if (!processListOutput.succeeded) {
Expand Down
Loading