diff options
Diffstat (limited to 'lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts')
| -rw-r--r-- | lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts | 89 |
1 files changed, 86 insertions, 3 deletions
diff --git a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts index 157aa2ac76a1..f7e92ee95ca3 100644 --- a/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts +++ b/lldb/tools/lldb-dap/src-ts/debug-adapter-factory.ts @@ -69,6 +69,40 @@ async function findDAPExecutable(): Promise<string | undefined> { } /** + * Validates the DAP environment provided in the debug configuration. + * It must be a dictionary of string keys and values OR an array of string values. + * + * @param debugConfigEnv The supposed DAP environment that will be validated + * @returns Whether or not the DAP environment is valid + */ +function validateDAPEnv(debugConfigEnv: any): boolean { + // If the env is an object, it should have string values. + // The keys are guaranteed to be strings. + if ( + typeof debugConfigEnv === "object" && + Object.values(debugConfigEnv).findIndex( + (entry) => typeof entry !== "string", + ) !== -1 + ) { + return false; + } + + // If the env is an array, it should have string values which match the regex. + if ( + Array.isArray(debugConfigEnv) && + debugConfigEnv.findIndex( + (entry) => + typeof entry !== "string" || !/^((\\w+=.*)|^\\w+)$/.test(entry), + ) !== -1 + ) { + return false; + } + + // The env is valid. + return true; +} + +/** * Retrieves the lldb-dap executable path either from settings or the provided * {@link vscode.DebugConfiguration}. * @@ -158,6 +192,51 @@ async function getDAPArguments( } /** + * Retrieves the environment that will be provided to lldb-dap either from settings or the provided + * {@link vscode.DebugConfiguration}. + * + * @param workspaceFolder The {@link vscode.WorkspaceFolder} that the debug session will be launched within + * @param configuration The {@link vscode.DebugConfiguration} that will be launched + * @throws An {@link ErrorWithNotification} if something went wrong + * @returns The environment that will be provided to lldb-dap + */ +async function getDAPEnvironment( + workspaceFolder: vscode.WorkspaceFolder | undefined, + configuration: vscode.DebugConfiguration, +): Promise<{ [key: string]: string }> { + const debugConfigEnv = configuration.debugAdapterEnv; + if (debugConfigEnv) { + if (validateDAPEnv(debugConfigEnv) === false) { + throw new ErrorWithNotification( + "The debugAdapterEnv property must be a dictionary of string keys and values OR an array of string values. Please update your launch configuration", + new ConfigureButton(), + ); + } + + // Transform, so that the returned value is always a dictionary. + if (Array.isArray(debugConfigEnv)) { + const ret: { [key: string]: string } = {}; + for (const envVar of debugConfigEnv as string[]) { + const equalSignPos = envVar.search("="); + if (equalSignPos >= 0) { + ret[envVar.substr(0, equalSignPos)] = envVar.substr(equalSignPos + 1); + } else { + ret[envVar] = ""; + } + } + return ret; + } else { + return debugConfigEnv; + } + } + + const config = vscode.workspace.workspaceFile + ? vscode.workspace.getConfiguration("lldb-dap") + : vscode.workspace.getConfiguration("lldb-dap", workspaceFolder); + return config.get<{ [key: string]: string }>("environment") || {}; +} + +/** * Creates a new {@link vscode.DebugAdapterExecutable} based on the provided workspace folder and * debug configuration. Assumes that the given debug configuration is for a local launch of lldb-dap. * @@ -182,12 +261,16 @@ export async function createDebugAdapterExecutable( if (log_path) { env["LLDBDAP_LOG"] = log_path; } else if ( - vscode.workspace.getConfiguration("lldb-dap").get("captureSessionLogs", false) + vscode.workspace + .getConfiguration("lldb-dap") + .get("captureSessionLogs", false) ) { env["LLDBDAP_LOG"] = logFilePath.get(LogType.DEBUG_SESSION); } - const configEnvironment = - config.get<{ [key: string]: string }>("environment") || {}; + const configEnvironment = await getDAPEnvironment( + workspaceFolder, + configuration, + ); const dapPath = await getDAPExecutable(workspaceFolder, configuration); const dbgOptions = { |
