Skip to content

Commit 7c0ad87

Browse files
committed
identifying lldb-dap version and using it in command context to enable symbols request
1 parent 7c7f477 commit 7c0ad87

File tree

6 files changed

+63
-36
lines changed

6 files changed

+63
-36
lines changed

lldb/tools/lldb-dap/Handler/ModuleSymbolsRequestHandler.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,23 @@ ModuleSymbolsRequestHandler::Run(const ModuleSymbolsArguments &args) const {
2626
ModuleSymbolsResponseBody response;
2727

2828
lldb::SBModuleSpec module_spec;
29-
if (args.moduleId) {
29+
if (!args.moduleId.empty()) {
3030
llvm::SmallVector<uint8_t, 20> uuid_bytes;
31-
if (!lldb_private::UUID::DecodeUUIDBytesFromString(*args.moduleId,
31+
if (!lldb_private::UUID::DecodeUUIDBytesFromString(args.moduleId,
3232
uuid_bytes)
3333
.empty())
3434
return llvm::make_error<DAPError>("Invalid module ID");
3535

3636
module_spec.SetUUIDBytes(uuid_bytes.data(), uuid_bytes.size());
3737
}
3838

39-
if (args.moduleName) {
39+
if (!args.moduleName.empty()) {
4040
lldb::SBFileSpec file_spec;
41-
file_spec.SetFilename(args.moduleName->c_str());
41+
file_spec.SetFilename(args.moduleName.c_str());
4242
module_spec.SetFileSpec(file_spec);
4343
}
4444

4545
// Empty request, return empty response.
46-
// We use it in the client to check if the lldb-dap server supports this
47-
// request.
4846
if (!module_spec.IsValid())
4947
return response;
5048

lldb/tools/lldb-dap/Protocol/ProtocolRequests.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -983,10 +983,10 @@ llvm::json::Value toJSON(const WriteMemoryResponseBody &);
983983

984984
struct ModuleSymbolsArguments {
985985
/// The module UUID for which to retrieve symbols.
986-
std::optional<std::string> moduleId;
986+
std::string moduleId;
987987

988988
/// The module path.
989-
std::optional<std::string> moduleName;
989+
std::string moduleName;
990990
};
991991
bool fromJSON(const llvm::json::Value &, ModuleSymbolsArguments &,
992992
llvm::json::Path);

lldb/tools/lldb-dap/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@
289289
},
290290
{
291291
"command": "lldb-dap.debug.showSymbols",
292-
"when": "debuggersAvailable && debugType == 'lldb-dap'"
292+
"when": "debuggersAvailable && debugType == 'lldb-dap' && lldb-dap.supportsModuleSymbolsRequest"
293293
}
294294
],
295295
"view/item/context": [
@@ -299,7 +299,7 @@
299299
},
300300
{
301301
"command": "lldb-dap.modules.showSymbols",
302-
"when": "view == lldb-dap.modules && viewItem == module"
302+
"when": "view == lldb-dap.modules && viewItem == module && lldb-dap.supportsModuleSymbolsRequest"
303303
}
304304
]
305305
},

lldb/tools/lldb-dap/src-ts/debug-configuration-provider.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ const configurations: Record<string, DefaultConfig> = {
6969
terminateCommands: { type: "stringArray", default: [] },
7070
};
7171

72+
export function getDefaultConfigKey(key: string): string | number | boolean | string[] | undefined {
73+
return configurations[key]?.default;
74+
}
75+
7276
export class LLDBDapConfigurationProvider
7377
implements vscode.DebugConfigurationProvider
7478
{

lldb/tools/lldb-dap/src-ts/debug-session-tracker.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as vscode from "vscode";
66
interface EventMap {
77
"module": DebugProtocol.ModuleEvent;
88
"exited": DebugProtocol.ExitedEvent;
9+
"initialized": DebugProtocol.InitializedEvent;
910
}
1011

1112
/** A type assertion to check if a ProtocolMessage is an event or if it is a specific event. */
@@ -39,6 +40,8 @@ export class DebugSessionTracker
3940
private modulesChanged = new vscode.EventEmitter<
4041
vscode.DebugSession | undefined
4142
>();
43+
private sessionInitialized = new vscode.EventEmitter<vscode.DebugSession>();
44+
private sessionExited = new vscode.EventEmitter<vscode.DebugSession>();
4245

4346
/**
4447
* Fired when modules are changed for any active debug session.
@@ -48,6 +51,14 @@ export class DebugSessionTracker
4851
onDidChangeModules: vscode.Event<vscode.DebugSession | undefined> =
4952
this.modulesChanged.event;
5053

54+
/** Fired when a debug session is initialized. */
55+
onDidInitializeSession: vscode.Event<vscode.DebugSession> =
56+
this.sessionInitialized.event;
57+
58+
/** Fired when a debug session is exiting. */
59+
onDidExitSession: vscode.Event<vscode.DebugSession> =
60+
this.sessionExited.event;
61+
5162
constructor(private logger: vscode.LogOutputChannel) {
5263
this.onDidChangeModules(this.moduleChangedListener, this);
5364
vscode.debug.onDidChangeActiveDebugSession((session) =>
@@ -146,6 +157,10 @@ export class DebugSessionTracker
146157
this.logger.info(
147158
`Session "${session.name}" exited with code ${exitCode}`,
148159
);
160+
161+
this.sessionExited.fire(session);
162+
} else if (isEvent(message, "initialized")) {
163+
this.sessionInitialized.fire(session);
149164
}
150165
}
151166
}

lldb/tools/lldb-dap/src-ts/ui/symbols-provider.ts

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { DebugSessionTracker } from "../debug-session-tracker";
55
import { DisposableContext } from "../disposable-context";
66

77
import { DAPSymbolType } from "..";
8+
import { getDefaultConfigKey } from "../debug-configuration-provider";
89

910
export class SymbolsProvider extends DisposableContext {
1011
constructor(
@@ -16,54 +17,64 @@ export class SymbolsProvider extends DisposableContext {
1617
this.pushSubscription(vscode.commands.registerCommand(
1718
"lldb-dap.debug.showSymbols",
1819
() => {
19-
this.SelectModuleAndShowSymbols();
20+
const session = vscode.debug.activeDebugSession;
21+
if (!session) return;
22+
23+
this.SelectModuleAndShowSymbols(session);
2024
},
2125
));
2226

2327
this.pushSubscription(vscode.commands.registerCommand(
2428
"lldb-dap.modules.showSymbols",
2529
(moduleItem: DebugProtocol.Module) => {
2630
const session = vscode.debug.activeDebugSession;
27-
if (!session) {
28-
return;
29-
}
31+
if (!session) return;
32+
3033
this.showSymbolsForModule(session, moduleItem);
3134
},
3235
));
33-
}
3436

35-
static async doesServerSupportSymbolsRequest(session: vscode.DebugSession): Promise<boolean> {
36-
try {
37-
const dummyArguments = { _dummy: true };
38-
await session.customRequest("moduleSymbols", dummyArguments);
39-
return true;
40-
} catch (_error) {
41-
return false;
42-
}
37+
this.tracker.onDidInitializeSession((session) => {
38+
this.GetLLDBServerVersion(session).then((version) => {
39+
if (version !== undefined) {
40+
if (version[0] >= 23) {
41+
vscode.commands.executeCommand("setContext", "lldb-dap.supportsModuleSymbolsRequest", true);
42+
}
43+
}
44+
});
45+
});
46+
47+
this.tracker.onDidExitSession((session) => {
48+
vscode.commands.executeCommand("setContext", "lldb-dap.supportsModuleSymbolsRequest", false);
49+
});
4350
}
4451

45-
private async SelectModuleAndShowSymbols() {
46-
const session = vscode.debug.activeDebugSession;
47-
if (!session) {
48-
return;
49-
}
52+
private async GetLLDBServerVersion(session: vscode.DebugSession): Promise<[number, number, number] | undefined> {
53+
const commandEscapePrefix = session.configuration.commandEscapePrefix || getDefaultConfigKey("commandEscapePrefix");
54+
const response = await session.customRequest("evaluate", { expression: commandEscapePrefix + "version", context: "repl" });
5055

51-
if (!await SymbolsProvider.doesServerSupportSymbolsRequest(session)) {
52-
vscode.window.showErrorMessage("The debug adapter does not support symbol requests.");
53-
return;
54-
}
56+
const versionLine = response.result?.split("\n")[0];
57+
if (!versionLine) return undefined;
58+
59+
const versionMatch = versionLine.match(/(\d+)\.(\d+)\.(\d+)/);
60+
if (!versionMatch) return undefined;
5561

62+
const [major, minor, patch] = versionMatch.slice(1, 4).map(Number);
63+
return [major, minor, patch];
64+
}
65+
66+
private async SelectModuleAndShowSymbols(session: vscode.DebugSession) {
5667
const modules = this.tracker.debugSessionModules(session);
5768
if (!modules || modules.length === 0) {
58-
return;
69+
return;
5970
}
6071

6172
// Let the user select a module to show symbols for
6273
const selectedModule = await vscode.window.showQuickPick(modules.map(m => new ModuleQuickPickItem(m)), {
6374
placeHolder: "Select a module to show symbols for"
6475
});
6576
if (!selectedModule) {
66-
return;
77+
return;
6778
}
6879

6980
this.showSymbolsForModule(session, selectedModule.module);
@@ -86,8 +97,7 @@ export class SymbolsProvider extends DisposableContext {
8697

8798
private async getSymbolsForModule(session: vscode.DebugSession, moduleId: string): Promise<DAPSymbolType[]> {
8899
console.log(`Getting symbols for module: ${moduleId}`);
89-
const symbols_response: { symbols: Array<DAPSymbolType> } = await session.customRequest("moduleSymbols", { moduleId });
90-
100+
const symbols_response: { symbols: Array<DAPSymbolType> } = await session.customRequest("moduleSymbols", { moduleId, moduleName: '' });
91101

92102
return symbols_response?.symbols || [];
93103
}

0 commit comments

Comments
 (0)