asmimproved-dbgmits
Version:
Provides the ability to control GDB and LLDB programmatically via GDB/MI.
293 lines (290 loc) • 30.6 kB
JavaScript
// Copyright (c) 2015 Vadim Macagon
// MIT License, see LICENSE file for full terms.
;
require('source-map-support').install();
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
var stream = require('stream');
var dbgmits = require('../lib/index');
var test_utils_1 = require('./test_utils');
chai.use(chaiAsPromised);
// aliases
var expect = chai.expect;
var DebugSession = dbgmits.DebugSession;
// the directory in which Gruntfile.js resides is also Mocha's working directory,
// so any relative paths will be relative to that directory
var localTargetExe = './build/Debug/test_target';
var hostExecutable = 'C:/Projects/hello-world/hello-world';
var remoteHost = '192.168.56.101';
var remotePort = 8099;
/**
* Creates a readable stream containing nothing but the text passed in.
*/
function createTextStream(text) {
var textStream = new stream.Readable();
textStream.push(text, 'utf8');
textStream.push(null);
return textStream;
}
/**
* Creates a debug session but instead of spawning a debugger and connecting to it the session
* is simply fed the passed in notification text, this makes it emit an event (assuming the
* notification text was formatted correctly).
*
* @param text Notification text in MI format.
* @param event The name of the event that is expected to be emitted.
* @param callback Callback to invoke if the expected event was emitted.
*/
function emitEventForDebuggerOutput(text, event, callback) {
var debugSession = new DebugSession(createTextStream(text), null);
debugSession.once(event, function (data) {
debugSession.end(false);
callback(data);
});
}
describe("Debug Session", function () {
describe("Basics", function () {
var debugSession;
before(function () {
debugSession = test_utils_1.startDebugSession();
});
it("should start", function () {
expect(debugSession).to.exist;
});
it("should set executable to debug", function () {
return debugSession.setExecutableFile(localTargetExe);
});
after(function () {
return debugSession.end();
});
});
describe("Events", function () {
it("emits EVENT_THREAD_GROUP_ADDED", function (done) {
var id = 'i1';
emitEventForDebuggerOutput("=thread-group-added,id=\"" + id + "\"\n", dbgmits.EVENT_THREAD_GROUP_ADDED, function (data) {
expect(data).to.have.property('id', id);
done();
});
});
it("emits EVENT_THREAD_GROUP_REMOVED", function (done) {
var id = 'i1';
emitEventForDebuggerOutput("=thread-group-removed,id=\"" + id + "\"\n", dbgmits.EVENT_THREAD_GROUP_REMOVED, function (data) {
expect(data).to.have.property('id', id);
done();
});
});
it("emits EVENT_THREAD_GROUP_STARTED", function (done) {
var id = 'i1';
var pid = '6550';
emitEventForDebuggerOutput("=thread-group-started,id=\"" + id + "\",pid=\"" + pid + "\"\n", dbgmits.EVENT_THREAD_GROUP_STARTED, function (data) {
expect(data).to.have.property('id', id);
expect(data).to.have.property('pid', pid);
done();
});
});
it("emits EVENT_THREAD_GROUP_EXITED", function (done) {
var id = 'i1';
var exitCode = '3';
emitEventForDebuggerOutput("=thread-group-exited,id=\"" + id + "\",exit-code=\"" + exitCode + "\"\n", dbgmits.EVENT_THREAD_GROUP_EXITED, function (data) {
expect(data).to.have.property('id', id);
expect(data).to.have.property('exitCode', exitCode);
done();
});
});
it("emits EVENT_THREAD_CREATED", function (done) {
var id = 1;
var groupId = 'i1';
emitEventForDebuggerOutput("=thread-created,id=\"" + id + "\",group-id=\"" + groupId + "\"\n", dbgmits.EVENT_THREAD_CREATED, function (data) {
expect(data).to.have.property('id', id);
expect(data).to.have.property('groupId', groupId);
done();
});
});
it("emits EVENT_THREAD_EXITED", function (done) {
var id = 1;
var groupId = 'i1';
emitEventForDebuggerOutput("=thread-exited,id=\"" + id + "\",group-id=\"" + groupId + "\"\n", dbgmits.EVENT_THREAD_EXITED, function (data) {
expect(data).to.have.property('id', id);
expect(data).to.have.property('groupId', groupId);
done();
});
});
it("emits EVENT_THREAD_SELECTED", function (done) {
var id = 1;
emitEventForDebuggerOutput("=thread-selected,id=\"" + id + "\"\n", dbgmits.EVENT_THREAD_SELECTED, function (data) {
expect(data).to.have.property('id', id);
done();
});
});
it("emits EVENT_LIB_LOADED", function (done) {
var id = '1';
var targetName = 'somelib';
var hostName = 'somelib';
var threadGroup = 'i1';
emitEventForDebuggerOutput("=library-loaded,id=\"" + id + "\",target-name=\"" + targetName + "\",host-name=\"" + hostName + "\",thread-group=\"" + threadGroup + "\"\n", dbgmits.EVENT_LIB_LOADED, function (data) {
expect(data).to.have.property('id', id);
expect(data).to.have.property('targetName', targetName);
expect(data).to.have.property('hostName', hostName);
expect(data).to.have.property('threadGroup', threadGroup);
done();
});
});
it("emits EVENT_LIB_UNLOADED", function (done) {
var id = '1';
var targetName = 'somelib';
var hostName = 'somelib';
var threadGroup = 'i1';
emitEventForDebuggerOutput("=library-unloaded,id=\"" + id + "\",target-name=\"" + targetName + "\",host-name=\"" + hostName + "\",thread-group=\"" + threadGroup + "\"\n", dbgmits.EVENT_LIB_UNLOADED, function (data) {
expect(data).to.have.property('id', id);
expect(data).to.have.property('targetName', targetName);
expect(data).to.have.property('hostName', hostName);
expect(data).to.have.property('threadGroup', threadGroup);
done();
});
});
it("emits EVENT_DBG_CONSOLE_OUTPUT", function (done) {
var testStr = 'This is a line of text.';
emitEventForDebuggerOutput('~"' + testStr + '"\n', dbgmits.EVENT_DBG_CONSOLE_OUTPUT, function (data) {
expect(data).to.equal(testStr);
done();
});
});
it("emits EVENT_TARGET_OUTPUT", function (done) {
var testStr = 'This is some target output.';
emitEventForDebuggerOutput('@"' + testStr + '"\n', dbgmits.EVENT_TARGET_OUTPUT, function (data) {
expect(data).to.equal(testStr);
done();
});
});
it("emits EVENT_DBG_LOG_OUTPUT", function (done) {
var testStr = 'This is some debugger log output.';
emitEventForDebuggerOutput('&"' + testStr + '"\n', dbgmits.EVENT_DBG_LOG_OUTPUT, function (data) {
expect(data).to.equal(testStr);
done();
});
});
it("emits EVENT_TARGET_RUNNING", function (done) {
var threadId = 'all';
emitEventForDebuggerOutput('*running,thread-id="${threadId}"', dbgmits.EVENT_TARGET_RUNNING, function (threadId) {
expect(threadId).to.equal(threadId);
done();
});
});
it("emits EVENT_TARGET_STOPPED", function (done) {
emitEventForDebuggerOutput('*stopped,reason="exited-normally"\n', dbgmits.EVENT_TARGET_STOPPED, function (notification) {
expect(notification.reason).to.equal(dbgmits.TargetStopReason.ExitedNormally);
done();
});
});
it("emits EVENT_BREAKPOINT_HIT", function (done) {
var bkptId = 15;
var threadId = 1;
emitEventForDebuggerOutput(("*stopped,reason=\"breakpoint-hit\",bkptno=\"" + bkptId + "\",frame={},thread-id=\"" + threadId + "\",") +
"stopped-threads=\"all\"\n", dbgmits.EVENT_BREAKPOINT_HIT, function (notification) {
expect(notification.reason).to.equal(dbgmits.TargetStopReason.BreakpointHit);
expect(notification.threadId).to.equal(threadId);
expect(notification.stoppedThreads.length).to.equal(0);
expect(notification.breakpointId).to.equal(bkptId);
done();
});
});
it("emits EVENT_SIGNAL_RECEIVED", function (done) {
var signalName = 'SIGSEGV';
var signalMeaning = 'Segmentation Fault';
var threadId = 1;
emitEventForDebuggerOutput(("*stopped,reason=\"signal-received\",signal-name=\"" + signalName + "\",") +
("signal-meaning=\"" + signalMeaning + "\",thread-id=\"" + threadId + "\",frame={}\n"), dbgmits.EVENT_SIGNAL_RECEIVED, function (notification) {
expect(notification.reason).to.equal(dbgmits.TargetStopReason.SignalReceived);
expect(notification.threadId).to.equal(threadId);
expect(notification.signalName).to.equal(signalName);
expect(notification.signalMeaning).to.equal(signalMeaning);
done();
});
});
it("emits EVENT_EXCEPTION_RECEIVED", function (done) {
var msg = 'This is an exception description.';
var threadId = 1;
emitEventForDebuggerOutput(("*stopped,reason=\"exception-received\",exception=\"" + msg + "\",thread-id=\"" + threadId + "\",") +
"stopped-threads=\"all\"\n", dbgmits.EVENT_EXCEPTION_RECEIVED, function (notification) {
expect(notification.reason).to.equal(dbgmits.TargetStopReason.ExceptionReceived);
expect(notification.threadId).to.equal(threadId);
expect(notification.stoppedThreads.length).to.equal(0);
expect(notification.exception).to.equal(msg);
done();
});
});
it("emits EVENT_BREAKPOINT_MODIFIED", function (done) {
var id = 999;
var breakpointType = 'breakpoint';
var address = '0x0000000000400927';
var func = 'main(int, char const**)';
var filename = '../test/break_tests_target.cpp';
var fullname = '/media/sf_dbgmits/test/break_tests_target.cpp';
var line = 47;
var threadGroup = 'i1';
var hitCount = 1;
var ignoreCount = 2;
var enableCount = 3;
var passCount = 4;
var originaLocation = 'main';
var threadId = 10;
var condition = 'something == true';
var what = 'nothing';
var at = address + " " + func;
var evaluatedBy = 'target';
var mask = "xxxx";
emitEventForDebuggerOutput(("=breakpoint-modified,bkpt={number=\"" + id + "\",type=\"" + breakpointType + "\",disp=\"keep\",") +
("enabled=\"y\",addr=\"" + address + "\",func=\"" + func + "\",file=\"" + filename + "\",") +
("fullname=\"" + fullname + "\",line=\"" + line + "\",thread-groups=[\"" + threadGroup + "\"],") +
("times=\"" + hitCount + "\",enable=\"" + enableCount + "\",ignore=\"" + ignoreCount + "\",") +
("original-location=\"" + originaLocation + "\",pending=\"" + originaLocation + "\",") +
("thread=\"" + threadId + "\",cond=\"" + condition + "\",what=\"" + what + "\",at=\"" + at + "\",") +
("pass=\"" + passCount + "\",evaluated-by=\"" + evaluatedBy + "\",mask=\"" + mask + "\",") +
"installed=\"y\"}", dbgmits.EVENT_BREAKPOINT_MODIFIED, function (e) {
var bp = e.breakpoint;
expect(bp).to.have.property('id', id);
expect(bp).to.have.property('breakpointType', breakpointType);
expect(bp).to.have.property('isTemp', false);
expect(bp).to.have.property('isEnabled', true);
expect(bp).to.have.property('locations').of.length(1);
expect(bp).to.have.property('pending', originaLocation);
expect(bp).to.have.property('threadId', threadId);
expect(bp).to.have.property('condition', condition);
expect(bp).to.have.property('ignoreCount', ignoreCount);
expect(bp).to.have.property('enableCount', enableCount);
expect(bp).to.have.property('originalLocation', originaLocation);
expect(bp).to.have.property('hitCount', hitCount);
expect(bp).to.have.property('what', what);
expect(bp).to.have.property('passCount', passCount);
expect(bp).to.have.property('evaluatedBy', evaluatedBy);
expect(bp).to.have.property('mask', mask);
expect(bp).to.have.property('isInstalled', true);
var bploc = bp.locations[0];
expect(bploc).to.have.property('id', id.toString());
expect(bploc).to.have.property('address', address);
expect(bploc).to.have.property('func', func);
expect(bploc).to.have.property('filename', filename);
expect(bploc).to.have.property('fullname', fullname);
expect(bploc).to.have.property('line', line);
expect(bploc).to.have.property('at', at);
done();
});
});
});
/*
describe("Remote Debugging Setup", () => {
var debugSession: DebugSession;
before(() => {
debugSession = startDebugSession();
return debugSession.setExecutableFile(hostExecutable);
});
it("should connect to remote target", () => {
return debugSession.connectToRemoteTarget(remoteHost, remotePort);
});
after(() => {
return debugSession.end();
});
});
*/
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzaWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90ZXN0L2Jhc2ljLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG1DQUFtQztBQUNuQyxnREFBZ0Q7O0FBRWhELE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBRXhDLElBQVksSUFBSSxXQUFNLE1BQU0sQ0FBQyxDQUFBO0FBQzdCLElBQU8sY0FBYyxXQUFXLGtCQUFrQixDQUFDLENBQUM7QUFDcEQsSUFBWSxNQUFNLFdBQU0sUUFBUSxDQUFDLENBQUE7QUFFakMsSUFBWSxPQUFPLFdBQU0sY0FBYyxDQUFDLENBQUE7QUFDeEMsMkJBQWtDLGNBQWMsQ0FBQyxDQUFBO0FBRWpELElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7QUFFekIsVUFBVTtBQUNWLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDekIsSUFBTyxZQUFZLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztBQUUzQyxpRkFBaUY7QUFDakYsMkRBQTJEO0FBQzNELElBQUksY0FBYyxHQUFXLDJCQUEyQixDQUFDO0FBQ3pELElBQUksY0FBYyxHQUFXLHFDQUFxQyxDQUFDO0FBQ25FLElBQUksVUFBVSxHQUFXLGdCQUFnQixDQUFDO0FBQzFDLElBQUksVUFBVSxHQUFXLElBQUksQ0FBQztBQUU5Qjs7R0FFRztBQUNILDBCQUEwQixJQUFZO0lBQ3BDLElBQUksVUFBVSxHQUFHLElBQUksTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3ZDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzlCLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEIsTUFBTSxDQUFDLFVBQVUsQ0FBQztBQUNwQixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxvQ0FBb0MsSUFBWSxFQUFFLEtBQWEsRUFBRSxRQUE2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