UNPKG

si-debug

Version:

GDB, LLDB & Mago-MI Debugger support for SuperIDE

74 lines (67 loc) 3.13 kB
import { MI2, escape } from "./mi2"; import { Breakpoint } from "../backend"; import * as ChildProcess from "child_process"; import * as path from "path"; export class MI2_LLDB extends MI2 { protected override initCommands(target: string, cwd: string, attach: boolean = false) { // We need to account for the possibility of the path type used by the debugger being different // than the path type where the extension is running (e.g., SSH from Linux to Windows machine). // Since the CWD is expected to be an absolute path in the debugger's environment, we can test // that to determine the path type used by the debugger and use the result of that test to // select the correct API to check whether the target path is an absolute path. const debuggerPath = path.posix.isAbsolute(cwd) ? path.posix : path.win32; if (!debuggerPath.isAbsolute(target)) target = debuggerPath.join(cwd, target); const cmds = [ this.sendCommand("gdb-set target-async on"), new Promise(resolve => { this.sendCommand("list-features").then(done => { this.features = done.result("features"); resolve(undefined); }, err => { this.features = []; resolve(undefined); }); }) ]; if (!attach) cmds.push(this.sendCommand("file-exec-and-symbols \"" + escape(target) + "\"")); for (const cmd of this.extraCommands) { cmds.push(this.sendCliCommand(cmd)); } return cmds; } override attach(cwd: string, executable: string, target: string, autorun: string[]): Thenable<any> { return new Promise((resolve, reject) => { const args = this.preargs.concat(this.extraargs || []); this.process = ChildProcess.spawn(this.application, args, { cwd: cwd, env: this.procEnv }); this.process.stdout.on("data", this.stdout.bind(this)); this.process.stderr.on("data", this.stderr.bind(this)); this.process.on("exit", (() => { this.emit("quit"); }).bind(this)); this.process.on("error", ((err) => { this.emit("launcherror", err); }).bind(this)); const promises = this.initCommands(target, cwd, true); promises.push(this.sendCommand("file-exec-and-symbols \"" + escape(executable) + "\"")); promises.push(this.sendCommand("target-attach " + target)); promises.push(...autorun.map(value => { return this.sendUserInput(value); })); Promise.all(promises).then(() => { this.emit("debug-ready"); resolve(undefined); }, reject); }); } override setBreakPointCondition(bkptNum: number, condition: string): Thenable<any> { return this.sendCommand("break-condition " + bkptNum + " \"" + escape(condition) + "\" 1"); } override goto(filename: string, line: number): Thenable<Boolean> { return new Promise((resolve, reject) => { // LLDB parses the file differently than GDB... // GDB doesn't allow quoting only the file but only the whole argument // LLDB doesn't allow quoting the whole argument but rather only the file const target: string = (filename ? '"' + escape(filename) + '":' : "") + line; this.sendCliCommand("jump " + target).then(() => { this.emit("step-other", undefined); resolve(true); }, reject); }); } }