Added support for attaching & connecting to gdbserver (fix #4, fix #5)

This commit is contained in:
WebFreak001 2016-02-04 15:45:10 +01:00
commit 99217775cf
5 changed files with 139 additions and 8 deletions

View file

@ -14,8 +14,11 @@ export interface Stack {
export interface IBackend {
load(cwd: string, target: string): Thenable<any>;
attach(cwd: string, executable: string, target: string): Thenable<any>;
connect(cwd: string, executable: string, target: string): Thenable<any>;
start(): Thenable<boolean>;
stop();
detach();
interrupt(): Thenable<boolean>;
continue(): Thenable<boolean>;
next(): Thenable<boolean>;

View file

@ -12,6 +12,7 @@ export class MI2 extends EventEmitter implements IBackend {
return new Promise((resolve, reject) => {
this.process = ChildProcess.spawn(this.application, this.preargs.concat([target]), { cwd: cwd });
this.process.stdout.on("data", this.stdout.bind(this));
this.process.stderr.on("data", this.stdout.bind(this));
this.process.on("exit", (() => { this.emit("quit"); }).bind(this));
Promise.all([
this.sendCommand("environment-directory \"" + cwd + "\"")
@ -19,6 +20,40 @@ export class MI2 extends EventEmitter implements IBackend {
});
}
attach(cwd: string, executable: string, target: string): Thenable<any> {
return new Promise((resolve, reject) => {
let args = [];
if (!executable)
executable = "-p";
args = args.concat([executable, target], this.preargs);
this.process = ChildProcess.spawn(this.application, args, { cwd: cwd });
this.process.stdout.on("data", this.stdout.bind(this));
this.process.stderr.on("data", this.stdout.bind(this));
this.process.on("exit", (() => { this.emit("quit"); }).bind(this));
Promise.all([
this.sendCommand("environment-directory \"" + cwd + "\"")
]).then(resolve, reject);
});
}
connect(cwd: string, executable: string, target: string): Thenable<any> {
return new Promise((resolve, reject) => {
let args = [];
if (executable)
args = args.concat([executable], this.preargs);
else
args = this.preargs;
this.process = ChildProcess.spawn(this.application, args, { cwd: cwd });
this.process.stdout.on("data", this.stdout.bind(this));
this.process.stderr.on("data", this.stdout.bind(this));
this.process.on("exit", (() => { this.emit("quit"); }).bind(this));
Promise.all([
this.sendCommand("environment-directory \"" + cwd + "\""),
this.sendCommand("target-select remote " + target)
]).then(resolve, reject);
});
}
stdout(data) {
this.buffer += data.toString("utf8");
let end = this.buffer.lastIndexOf('\n');
@ -88,13 +123,24 @@ export class MI2 extends EventEmitter implements IBackend {
stop() {
let proc = this.process;
let to = setTimeout(() => {
proc.kill();
}, 2222);
process.kill(-proc.pid);
}, 1000);
this.process.on("exit", function(code) {
clearTimeout(to);
});
this.sendRaw("-gdb-exit");
}
detach() {
let proc = this.process;
let to = setTimeout(() => {
process.kill(-proc.pid);
}, 1000);
this.process.on("exit", function(code) {
clearTimeout(to);
});
this.sendRaw("-target-detach");
}
interrupt(): Thenable<boolean> {
return new Promise((resolve, reject) => {

View file

@ -10,11 +10,19 @@ export interface LaunchRequestArguments {
target: string;
}
export interface AttachRequestArguments {
cwd: string;
target: string;
executable: string;
remote: boolean;
}
class MI2DebugSession extends DebugSession {
private static THREAD_ID = 1;
private gdbDebugger: MI2;
private variableHandles = new Handles<any>();
private quit: boolean;
private attached: boolean;
public constructor(debuggerLinesStartAt1: boolean, isServer: boolean = false) {
super(debuggerLinesStartAt1, isServer);
@ -43,9 +51,9 @@ class MI2DebugSession extends DebugSession {
private handleBreak(info: MINode) {
this.sendEvent(new StoppedEvent("step", MI2DebugSession.THREAD_ID));
}
private stopEvent(info: MINode) {
if(!this.quit)
if (!this.quit)
this.sendEvent(new StoppedEvent("exception", MI2DebugSession.THREAD_ID));
}
@ -55,6 +63,8 @@ class MI2DebugSession extends DebugSession {
}
protected launchRequest(response: DebugProtocol.LaunchResponse, args: LaunchRequestArguments): void {
this.quit = false;
this.attached = false;
this.gdbDebugger.load(args.cwd, args.target).then(() => {
this.gdbDebugger.start().then(() => {
this.sendResponse(response);
@ -62,8 +72,26 @@ class MI2DebugSession extends DebugSession {
});
}
protected attachRequest(response: DebugProtocol.AttachResponse, args: AttachRequestArguments): void {
this.quit = false;
this.attached = !args.remote;
if (args.remote) {
this.gdbDebugger.connect(args.cwd, args.executable, args.target).then(() => {
this.sendResponse(response);
});
}
else {
this.gdbDebugger.attach(args.cwd, args.executable, args.target).then(() => {
this.sendResponse(response);
});
}
}
protected disconnectRequest(response: DebugProtocol.DisconnectResponse, args: DebugProtocol.DisconnectArguments): void {
this.gdbDebugger.stop();
if (this.attached)
this.gdbDebugger.detach();
else
this.gdbDebugger.stop();
this.sendResponse(response);
}