Skip to content

Commit

Permalink
Fix lldb-dap path on Darwin (#1008)
Browse files Browse the repository at this point in the history
* Fix lldb-dap path on Darwin

The `lldb-dap` binary is not in the toolchain directory on Darwin like
it is on Linux and Windows. Use `xcrun -find lldb-dap` on Darwin to find
the correct `lldb-dap` location.
  • Loading branch information
plemarquand authored Aug 15, 2024
1 parent 4488c31 commit e0a0fba
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 44 deletions.
4 changes: 2 additions & 2 deletions src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export interface DebuggerConfiguration {
/** Are we using debug adapter provided with Toolchain */
readonly useDebugAdapterFromToolchain: boolean;
/** Return path to debug adapter */
readonly debugAdapterPath: string;
readonly customDebugAdapterPath: string;
}

/** workspace folder configuration */
Expand Down Expand Up @@ -149,7 +149,7 @@ const configuration = {
.getConfiguration("swift.debugger")
.get<boolean>("useDebugAdapterFromToolchain", false);
},
get debugAdapterPath(): string {
get customDebugAdapterPath(): string {
return vscode.workspace.getConfiguration("swift.debugger").get<string>("path", "");
},
};
Expand Down
31 changes: 22 additions & 9 deletions src/debugger/debugAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import contextKeys from "../contextKeys";
import { fileExists } from "../utilities/filesystem";
import { Version } from "../utilities/version";
import { WorkspaceContext } from "../WorkspaceContext";
import { SwiftToolchain } from "../toolchain/toolchain";

/**
* Class managing which debug adapter we are using. Will only setup lldb-vscode/lldb-dap if it is available.
Expand All @@ -33,10 +34,25 @@ export class DebugAdapter {
}

/** Return debug adapter for toolchain */
public static getDebugAdapter(swiftVersion: Version): string {
public static getDebugAdapter(swiftVersion: Version): "lldb-vscode" | "lldb-dap" {
return swiftVersion.isLessThan(new Version(6, 0, 0)) ? "lldb-vscode" : "lldb-dap";
}

/** Return the path to the debug adapter */
public static async debugAdapterPath(toolchain: SwiftToolchain): Promise<string> {
const customDebugAdapterPath = configuration.debugger.customDebugAdapterPath;
if (customDebugAdapterPath.length > 0) {
return customDebugAdapterPath;
}

const debugAdapter = this.getDebugAdapter(toolchain.swiftVersion);
if (process.platform === "darwin" && debugAdapter === "lldb-dap") {
return await toolchain.getLLDBDebugAdapter();
} else {
return toolchain.getToolchainExecutable(debugAdapter);
}
}

/**
* Verify that the toolchain debug adapter exists
* @param workspace WorkspaceContext
Expand All @@ -47,18 +63,15 @@ export class DebugAdapter {
workspace: WorkspaceContext,
quiet = false
): Promise<boolean> {
const useCustom = configuration.debugger.debugAdapterPath.length > 0;
const debugAdapter = DebugAdapter.getDebugAdapter(workspace.toolchain.swiftVersion);
const lldbDebugAdapterPath = useCustom
? configuration.debugger.debugAdapterPath
: workspace.toolchain.getToolchainExecutable(debugAdapter);
const lldbDebugAdapterPath = await this.debugAdapterPath(workspace.toolchain);

if (!(await fileExists(lldbDebugAdapterPath))) {
if (!quiet) {
const debugAdapterName = this.getDebugAdapter(workspace.toolchain.swiftVersion);
vscode.window.showErrorMessage(
useCustom
? `Cannot find ${debugAdapter} debug adapter specified in setting Swift.Debugger.Path.`
: `Cannot find ${debugAdapter} debug adapter in your Swift toolchain.`
configuration.debugger.customDebugAdapterPath.length > 0
? `Cannot find ${debugAdapterName} debug adapter specified in setting Swift.Debugger.Path.`
: `Cannot find ${debugAdapterName} debug adapter in your Swift toolchain.`
);
}
workspace.outputChannel.log(`Failed to find ${lldbDebugAdapterPath}`);
Expand Down
24 changes: 8 additions & 16 deletions src/debugger/debugAdapterFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import * as vscode from "vscode";
import { WorkspaceContext } from "../WorkspaceContext";
import configuration from "../configuration";
import { DebugAdapter } from "./debugAdapter";

export function registerLLDBDebugAdapter(workspaceContext: WorkspaceContext): vscode.Disposable {
Expand All @@ -23,23 +22,16 @@ export function registerLLDBDebugAdapter(workspaceContext: WorkspaceContext): vs
_session: vscode.DebugSession,
executable: vscode.DebugAdapterExecutable | undefined
): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
// use the executable specified in the settings or use version in toolchain
const debugAdapter = DebugAdapter.getDebugAdapter(
workspaceContext.toolchain.swiftVersion
);
if (!executable) {
const lldbDebugAdapterPath =
configuration.debugger.debugAdapterPath.length > 0
? configuration.debugger.debugAdapterPath
: workspaceContext.toolchain.getToolchainExecutable(debugAdapter);
DebugAdapter.verifyDebugAdapterExists(workspaceContext).then(() => {
/** Ignore */
});
executable = new vscode.DebugAdapterExecutable(lldbDebugAdapterPath, [], {});
if (executable) {
// make VS Code launch the debug adapter executable
return executable;
}

// make VS Code launch the debug adapter executable
return executable;
return DebugAdapter.debugAdapterPath(workspaceContext.toolchain)
.then(path =>
DebugAdapter.verifyDebugAdapterExists(workspaceContext).then(() => path)
)
.then(path => new vscode.DebugAdapterExecutable(path, [], {}));
}
}

Expand Down
63 changes: 46 additions & 17 deletions src/toolchain/toolchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,28 +354,57 @@ export class SwiftToolchain {
}

/**
* Cannot use `getToolchainExecutable` to get the LLDB executable as LLDB
* is not in macOS toolchain path
* Returns the path to the LLDB executable inside the selected toolchain.
* If the user is on macOS and has no OSS toolchain selected, also search
* inside Xcode.
* @returns The path to the `lldb` executable
* @throws Throws an error if the executable cannot be found
*/
public async getLLDB(): Promise<string> {
let lldbPath = path.join(
return this.findToolchainOrXcodeExecutable("lldb");
}

/**
* Returns the path to the LLDB debug adapter executable inside the selected
* toolchain. If the user is on macOS and has no OSS toolchain selected, also
* search inside Xcode.
* @returns The path to the `lldb-dap` executable
* @throws Throws an error if the executable cannot be found
*/
public async getLLDBDebugAdapter(): Promise<string> {
return this.findToolchainOrXcodeExecutable("lldb-dap");
}

/**
* Search for the supplied executable in the toolchain.
* If the user is on macOS and has no OSS toolchain selected, also
* search inside Xcode.
*/
private async findToolchainOrXcodeExecutable(executable: string): Promise<string> {
const toolchainExecutablePath = path.join(
this.swiftFolderPath,
process.platform === "win32" ? "lldb.exe" : "lldb"
process.platform === "win32" ? `${executable}.exe` : executable
);
if (!(await pathExists(lldbPath))) {
if (process.platform !== "darwin") {
throw new Error("Failed to find LLDB in swift toolchain");
}
const xcodeDirectory = SwiftToolchain.getXcodeDirectory(this.swiftFolderPath);
if (!xcodeDirectory) {
throw new Error("Failed to find LLDB in swift toolchain");
}
const { stdout } = await execFile("xcrun", ["-find", "lldb"], {
env: { ...process.env, DEVELOPER_DIR: xcodeDirectory },
});
lldbPath = stdout.trimEnd();

if (await pathExists(toolchainExecutablePath)) {
return toolchainExecutablePath;
}
return lldbPath;

if (process.platform !== "darwin") {
throw new Error(`Failed to find ${executable} in swift toolchain`);
}
return this.findXcodeExecutable(executable);
}

private async findXcodeExecutable(executable: string): Promise<string> {
const xcodeDirectory = SwiftToolchain.getXcodeDirectory(this.toolchainPath);
if (!xcodeDirectory) {
throw new Error(`Failed to find ${executable} in Swift toolchain`);
}
const { stdout } = await execFile("xcrun", ["-find", executable], {
env: { ...process.env, DEVELOPER_DIR: xcodeDirectory },
});
return stdout.trimEnd();
}

private basePlatformDeveloperPath(): string | undefined {
Expand Down

0 comments on commit e0a0fba

Please sign in to comment.