|
|
@ -142,7 +142,10 @@ Client.prototype._onResponse = function(res) { |
|
|
|
|
|
|
|
if (res.headers.Type == 'connect') { |
|
|
|
// do nothing
|
|
|
|
console.log(res); |
|
|
|
this.emit('ready'); |
|
|
|
} else if (res.body && res.body.event == 'break') { |
|
|
|
this.emit('break', res.body); |
|
|
|
} else if (cb) { |
|
|
|
this._reqCallbacks.splice(i, 1); |
|
|
|
cb(res.body); |
|
|
@ -214,33 +217,76 @@ Client.prototype.reqScripts = function(cb) { |
|
|
|
|
|
|
|
Client.prototype.reqContinue = function(cb) { |
|
|
|
this.req({ command: 'continue' } , function (res) { |
|
|
|
if (cb) cb(res.body); |
|
|
|
if (cb) cb(res); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
var helpMessage = "Commands: scripts, backtrace, version, eval, help, quit"; |
|
|
|
|
|
|
|
function SourceUnderline(source_text, position) { |
|
|
|
if (!source_text) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// Create an underline with a caret pointing to the source position. If the
|
|
|
|
// source contains a tab character the underline will have a tab character in
|
|
|
|
// the same place otherwise the underline will have a space character.
|
|
|
|
var underline = ''; |
|
|
|
for (var i = 0; i < position; i++) { |
|
|
|
if (source_text[i] == '\t') { |
|
|
|
underline += '\t'; |
|
|
|
} else { |
|
|
|
underline += ' '; |
|
|
|
} |
|
|
|
} |
|
|
|
underline += '^'; |
|
|
|
|
|
|
|
// Return the source line text with the underline beneath.
|
|
|
|
return source_text + '\n' + underline; |
|
|
|
} |
|
|
|
|
|
|
|
function SourceInfo(body) { |
|
|
|
var result = ''; |
|
|
|
|
|
|
|
if (body.script) { |
|
|
|
if (body.script.name) { |
|
|
|
result += body.script.name; |
|
|
|
} else { |
|
|
|
result += '[unnamed]'; |
|
|
|
} |
|
|
|
} |
|
|
|
result += ' line '; |
|
|
|
result += body.sourceLine + 1; |
|
|
|
result += ' column '; |
|
|
|
result += body.sourceColumn + 1; |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function startInterface() { |
|
|
|
|
|
|
|
var i = readline.createInterface(process.stdout); |
|
|
|
var term = readline.createInterface(process.stdout); |
|
|
|
var stdin = process.openStdin(); |
|
|
|
stdin.addListener('data', function(chunk) { |
|
|
|
i.write(chunk); |
|
|
|
term.write(chunk); |
|
|
|
}); |
|
|
|
|
|
|
|
var prompt = 'debug> '; |
|
|
|
|
|
|
|
i.setPrompt(prompt); |
|
|
|
i.prompt(); |
|
|
|
term.setPrompt('debug> '); |
|
|
|
term.prompt(); |
|
|
|
|
|
|
|
var quitTried = false; |
|
|
|
|
|
|
|
function tryQuit() { |
|
|
|
if (quitTried) return; |
|
|
|
quitTried = true; |
|
|
|
i.close(); |
|
|
|
term.close(); |
|
|
|
console.log("debug done\n"); |
|
|
|
if (c.writable) { |
|
|
|
c.reqContinue(function (res) { |
|
|
@ -251,45 +297,64 @@ function startInterface() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
i.on('SIGINT', tryQuit); |
|
|
|
i.on('close', tryQuit); |
|
|
|
term.on('SIGINT', tryQuit); |
|
|
|
term.on('close', tryQuit); |
|
|
|
c.on('close', function () { |
|
|
|
process.exit(0); |
|
|
|
}); |
|
|
|
|
|
|
|
i.on('line', function(cmd) { |
|
|
|
term.on('line', function(cmd) { |
|
|
|
if (cmd == 'quit') { |
|
|
|
tryQuit(); |
|
|
|
} else if (/^help/.test(cmd)) { |
|
|
|
console.log(helpMessage); |
|
|
|
i.prompt(); |
|
|
|
term.prompt(); |
|
|
|
|
|
|
|
} else if ('version' == cmd) { |
|
|
|
c.reqVersion(function (v) { |
|
|
|
console.log(v); |
|
|
|
i.prompt(); |
|
|
|
term.prompt(); |
|
|
|
}); |
|
|
|
|
|
|
|
} else if ('backtrace' == cmd || 'bt' == cmd) { |
|
|
|
} else if (/^backtrace/.test(cmd) || /^bt/.test(cmd)) { |
|
|
|
c.reqBacktrace(function (bt) { |
|
|
|
console.log(bt); |
|
|
|
i.prompt(); |
|
|
|
if (/full/.test(cmd)) { |
|
|
|
console.log(bt); |
|
|
|
} else if (bt.totalFrames == 0) { |
|
|
|
console.log('(empty stack)'); |
|
|
|
} else { |
|
|
|
var result = 'Frames #' + bt.fromFrame + |
|
|
|
' to #' + (bt.toFrame - 1) + |
|
|
|
' of ' + bt.totalFrames + '\n'; |
|
|
|
for (j = 0; j < bt.frames.length; j++) { |
|
|
|
if (j != 0) result += '\n'; |
|
|
|
result += bt.frames[j].text; |
|
|
|
} |
|
|
|
console.log(result); |
|
|
|
} |
|
|
|
term.prompt(); |
|
|
|
}); |
|
|
|
|
|
|
|
} else if ('continue' == cmd || 'c' == cmd) { |
|
|
|
} else if (/^continue/.test(cmd) || /^c/.test(cmd)) { |
|
|
|
c.reqContinue(function (res) { |
|
|
|
console.log(res); |
|
|
|
i.prompt(); |
|
|
|
// Wait for break point. (disable raw mode?)
|
|
|
|
}); |
|
|
|
|
|
|
|
} else if (/^scripts/.test(cmd)) { |
|
|
|
c.reqScripts(function (res) { |
|
|
|
var text = res.map(function (x) { return x.text; }); |
|
|
|
console.log(text.join('\n')); |
|
|
|
i.prompt(); |
|
|
|
if (/full/.test(cmd)) { |
|
|
|
console.log(res); |
|
|
|
} else { |
|
|
|
var text = res.map(function (x) { return x.text; }); |
|
|
|
console.log(text.join('\n')); |
|
|
|
} |
|
|
|
term.prompt(); |
|
|
|
}); |
|
|
|
|
|
|
|
} else if (/^eval/.test(cmd)) { |
|
|
|
c.reqEval(cmd.slice(5), function (res) { |
|
|
|
console.log(res); |
|
|
|
i.prompt(); |
|
|
|
term.prompt(); |
|
|
|
}); |
|
|
|
|
|
|
|
} else { |
|
|
@ -297,17 +362,45 @@ function startInterface() { |
|
|
|
// If it's not all white-space print this error message.
|
|
|
|
console.log('Unknown command "%s". Try "help"', cmd); |
|
|
|
} |
|
|
|
i.prompt(); |
|
|
|
term.prompt(); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
c.on('unhandledResponse', function (res) { |
|
|
|
console.log("\r\nunhandled res:"); |
|
|
|
console.log(res.body); |
|
|
|
i.prompt(); |
|
|
|
console.log(res); |
|
|
|
term.prompt(); |
|
|
|
}); |
|
|
|
|
|
|
|
i.on('close', function() { |
|
|
|
stdin.destroy(); |
|
|
|
c.on('break', function (res) { |
|
|
|
var result = ''; |
|
|
|
if (res.body.breakpoints) { |
|
|
|
result += 'breakpoint'; |
|
|
|
if (res.body.breakpoints.length > 1) { |
|
|
|
result += 's'; |
|
|
|
} |
|
|
|
result += ' #'; |
|
|
|
for (var i = 0; i < res.body.breakpoints.length; i++) { |
|
|
|
if (i > 0) { |
|
|
|
result += ', #'; |
|
|
|
} |
|
|
|
result += res.body.breakpoints[i]; |
|
|
|
} |
|
|
|
} else { |
|
|
|
result += 'break'; |
|
|
|
} |
|
|
|
result += ' in '; |
|
|
|
result += res.body.invocationText; |
|
|
|
result += ', '; |
|
|
|
result += SourceInfo(res.body); |
|
|
|
result += '\n'; |
|
|
|
result += SourceUnderline(res.body.sourceLineText, res.body.sourceColumn); |
|
|
|
|
|
|
|
c.currentSourceLine = res.body.sourceLine; |
|
|
|
c.currentFrame = 0; |
|
|
|
|
|
|
|
console.log(result); |
|
|
|
|
|
|
|
term.prompt(); |
|
|
|
}); |
|
|
|
} |
|
|
|