Detach from debugger when front-end disconnects.
Modified session behaviour so that back-end closes session and detaches from the debugger when front-end web-socked disconnects. Changed handling of debugger-connection errors so that front-end displays popup window with error description when back-end cannot connect to debugger. When a session starts, all previously set breakpoints are removed, since they were already deactivated by V8 debugger.
This commit is contained in:
Родитель
faad7b051f
Коммит
6b93aa7dc6
|
@ -21,9 +21,7 @@ function onWebSocketConnected() {
|
|||
function onWebSocketMessage(message) {
|
||||
if (!message || message === 'ping') return;
|
||||
|
||||
if (message === 'debuggerWasDisabled') {
|
||||
WebInspector.debuggerModel.disableDebugger();
|
||||
} else if (message === 'showConsolePanel') {
|
||||
if (message === 'showConsolePanel') {
|
||||
InspectorFrontendAPI.showConsole();
|
||||
} else {
|
||||
InspectorBackend.dispatch(message);
|
||||
|
|
|
@ -93,8 +93,6 @@ DebuggerAgent.prototype = {
|
|||
done);
|
||||
},
|
||||
|
||||
// TODO(bajtos) Keep track of breakpoints - see implementation in session.js
|
||||
|
||||
setBreakpointByUrl: function(params, done) {
|
||||
// TODO(bajtos) - handle params.urlRegex
|
||||
var requestParams = {
|
||||
|
|
|
@ -5,10 +5,7 @@ var Http = require('http'),
|
|||
Session = require('./session'),
|
||||
inherits = require('util').inherits,
|
||||
WEBROOT = require('path').join(__dirname, '../front-end'),
|
||||
sessions = {},
|
||||
config = {},
|
||||
connectionTimeout,
|
||||
webPort;
|
||||
config = {};
|
||||
|
||||
function serveStaticFiles(req, res) {
|
||||
var re = /^\/debug/;
|
||||
|
@ -23,26 +20,16 @@ function getDebuggerPort(url, defaultPort) {
|
|||
return parseInt((/\?port=(\d+)/.exec(url) || [null, defaultPort])[1], 10);
|
||||
}
|
||||
|
||||
function getSession(debuggerPort) {
|
||||
var session = sessions[debuggerPort];
|
||||
if (!session) {
|
||||
session = Session.create(debuggerPort, config);
|
||||
sessions[debuggerPort] = session;
|
||||
session.on('ws_closed', function () {
|
||||
connectionTimeout = setTimeout(function () {
|
||||
session.close();
|
||||
}, 3000);
|
||||
});
|
||||
session.on('close', function () {
|
||||
sessions[debuggerPort] = null;
|
||||
});
|
||||
}
|
||||
function createSession(debuggerPort) {
|
||||
var session = Session.create(debuggerPort, config);
|
||||
session.on('ws_closed', function () {
|
||||
session.close();
|
||||
});
|
||||
return session;
|
||||
}
|
||||
|
||||
function handleWebSocketConnection(socket) {
|
||||
clearTimeout(connectionTimeout);
|
||||
getSession(config.debugPort).join(socket);
|
||||
createSession(config.debugPort).join(socket);
|
||||
}
|
||||
|
||||
function handleServerListening() {
|
||||
|
|
|
@ -34,6 +34,9 @@ exports.attachDebugger = function(port) {
|
|||
debugBuffer = b.toString('utf8', msg.contentLength, b.length);
|
||||
if (msg.body.length > 0) {
|
||||
obj = JSON.parse(msg.body);
|
||||
if (typeof obj.running === 'boolean') {
|
||||
debugr.isRunning = obj.running;
|
||||
}
|
||||
if (obj.type === 'response' && obj.request_seq > 0) {
|
||||
callbackHandler.processResponse(obj.request_seq, [obj]);
|
||||
}
|
||||
|
@ -67,6 +70,8 @@ exports.attachDebugger = function(port) {
|
|||
}
|
||||
|
||||
debugr = Object.create(EventEmitter.prototype, {
|
||||
isRunning: { writable: true, value: true },
|
||||
|
||||
send: {
|
||||
value: function(data)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
var events = require('events'),
|
||||
async = require('async'),
|
||||
debugr = require('./debugger'),
|
||||
convert = require('./convert.js'),
|
||||
ScriptManager = require('./ScriptManager').ScriptManager;
|
||||
|
@ -163,20 +164,60 @@ exports.create = function(debuggerPort, config) {
|
|||
}
|
||||
}
|
||||
|
||||
function removeAllBreakpoints(done) {
|
||||
debug.sendDebugRequest('listbreakpoints', {}, function(error, response) {
|
||||
if (error) {
|
||||
console.log('Warning: cannot remove old breakpoints. %s', error);
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
function removeOneBreakpoint(bp, next) {
|
||||
var req = { breakpoint: bp.number };
|
||||
debug.sendDebugRequest('clearbreakpoint', req, function(error) {
|
||||
if (error)
|
||||
console.log(
|
||||
'Warning: cannot remove old breakpoint %d. %s',
|
||||
bp.number,
|
||||
error);
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
async.eachSeries(response.breakpoints, removeOneBreakpoint, done);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
function reloadScripts(done) {
|
||||
scriptManager.reset();
|
||||
// TODO(bajtos) use sendDebugRequest and handle errors
|
||||
debug.request(
|
||||
'scripts',
|
||||
{ arguments: { includeSource: true, types: 4 }},
|
||||
function(msg) {
|
||||
parsedScripts(msg);
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
function sendBacktraceIfPaused() {
|
||||
if (!debug.isRunning) {
|
||||
sendBacktrace();
|
||||
}
|
||||
}
|
||||
|
||||
function browserConnected() { // TODO find a better name
|
||||
sendPing();
|
||||
scriptManager.reset();
|
||||
var args = { arguments: { includeSource: true, types: 4 }};
|
||||
debug.request('scripts', args, function(msg) {
|
||||
parsedScripts(msg);
|
||||
// TODO(bajtos) we should probably clear all existing breakpoints here, because:
|
||||
|
||||
async.waterfall([
|
||||
// Remove all existing breakpoints because:
|
||||
// 1) front-end inspector cannot restore breakpoints from debugger anyway
|
||||
// 2) all breakpoints are disabled when debugger-client disconnects from
|
||||
// debugged application
|
||||
if (!msg.running) {
|
||||
sendBacktrace();
|
||||
}
|
||||
});
|
||||
// 2) all breakpoints were disabled when the previous debugger-client
|
||||
// disconnected from the debugged application
|
||||
removeAllBreakpoints,
|
||||
reloadScripts,
|
||||
sendBacktraceIfPaused,
|
||||
]);
|
||||
}
|
||||
|
||||
sessionInstance = Object.create(events.EventEmitter.prototype, {
|
||||
|
@ -202,12 +243,7 @@ exports.create = function(debuggerPort, config) {
|
|||
attach: {
|
||||
value: function(done)
|
||||
{
|
||||
if (attachedToDebugger) {
|
||||
// TODO(bajtos) duplicated code - see debug.on('connect')
|
||||
done();
|
||||
browserConnected();
|
||||
return;
|
||||
}
|
||||
var closeReason = 'Debugged process exited.';
|
||||
debug = debugr.attachDebugger(debuggerPort);
|
||||
debug.on('break', breakEvent);
|
||||
debug.on('afterCompile', onAfterCompile)
|
||||
|
@ -216,16 +252,15 @@ exports.create = function(debuggerPort, config) {
|
|||
debug = {
|
||||
request: function() {
|
||||
console.error('debugger not connected');
|
||||
},
|
||||
sendDebugRequest: function(command, args, callback) {
|
||||
callback('debugger not connected');
|
||||
}
|
||||
};
|
||||
if (conn)
|
||||
conn.send('debuggerWasDisabled');
|
||||
// Do not close the session - keep it for debugee restart
|
||||
// self.close();
|
||||
attachedToDebugger = false;
|
||||
sendEvent('Inspector.detached', { reason: closeReason.replace(/\n/g, '. ') });
|
||||
sessionInstance.close();
|
||||
});
|
||||
debug.on('connect', function() {
|
||||
// TODO(bajtos) duplicated code - see if (attachedToDebugger)
|
||||
done();
|
||||
browserConnected();
|
||||
});
|
||||
|
@ -236,6 +271,10 @@ exports.create = function(debuggerPort, config) {
|
|||
var err = e.toString();
|
||||
if (err.match(/ECONNREFUSED/)) {
|
||||
err += '\nIs node running with --debug port ' + debuggerPort + '?';
|
||||
closeReason = err;
|
||||
} else if (err.match(/ECONNRESET/)) {
|
||||
err += '\nCheck there is no other debugger client attached to port ' + debuggerPort + '.';
|
||||
closeReason = err;
|
||||
}
|
||||
sendLogToConsole('error', err);
|
||||
});
|
||||
|
@ -253,6 +292,7 @@ exports.create = function(debuggerPort, config) {
|
|||
}
|
||||
},
|
||||
//Controller
|
||||
// TODO(bajtos) move this method to DebuggerAgent.js
|
||||
disableDebugger: {
|
||||
value: function(done) {
|
||||
if (debug && debug.connected) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче