Permalink
Browse files

Debugger: work in progress.

  • Loading branch information...
1 parent 668b1eb commit 3b2485b23b71f9c06d3860220043320f838a5a3f @c4milo committed May 25, 2012
Showing with 113 additions and 41 deletions.
  1. +61 −39 lib/debugger/debugger-client.js
  2. +1 −1 lib/debugger/index.js
  3. +51 −1 lib/debugger/translator.js
@@ -4,6 +4,7 @@
var net = require('net');
var util = require('util');
var translator = require('./translator');
+var V8Protocol = require('_debugger').Protocol;
/**
* DebuggerClient
@@ -23,6 +24,7 @@ var DebuggerClient = module.exports = function(notify) {
this.notify = notify;
this.queue = [];
this.port = 5858;
+ this.protocol = null;
};
(function() {
@@ -38,62 +40,55 @@ var DebuggerClient = module.exports = function(notify) {
};
/**
- * Callback function to received debug data coming out of
- * the debugee process.
+ * This callback function gets invoked by
+ * nodejs v8 protocol implementation
+ * once it receives the entire response
+ * from v8 debug agent.
*
- * @param {Buffer} data Data sent by v8 debug agent
+ * @param {Object} response The response serialized
+ * by the nodejs implementation of the v8 remote debugger protocol.
* @api private
*/
- this.onData = function(data) {
- data += '';
- var message = data.split('Content-Length:')[1].split('\r\n\r\n');
- var length = parseInt(message[0], 10) || 0;
-
- if (!length) {
- return;
- }
-
- /**
- * TODO Buffering, I deferred until I find an explicit
- * case where v8 chunks the response.
- *
- * If v8 is not chunking messages then
- * it's really unlikely that those messages will be
- * chunked at the application level and usually
- * TCP proxies don't mess up with application data.
- */
-
- var payload = message[1];
- try {
- paylaod = JSON.parse(payload);
- } catch(e) {
- console.log(e.stack);
- }
+ this.onV8Response = function(response) {
+ var payload = response.body;
+ //console.log(payload);
if (payload.type == 'event') {
- if (!translate[payload.event]) {
+ if (!translator[payload.event]) {
console.warn('webkit-devtools-agent: Translator function ' +
' not found for event: ' + payload.event);
return;
}
- this.notify(translate[payload.event](payload));
+ this.notify(translator[payload.event](payload));
} else if (payload.type == 'response') {
var callback = this.requests[payload.request_seq];
if (callback) {
- callback(translate[payload.command](payload));
+ callback(translator[payload.command](payload));
delete this.requests[payload.request_seq];
} else {
console.warn('webkit-devtools-agent: Unexpected '+
'message was received, there is no callback function '+
- ' to handle it :( :' + payload);
+ ' to handle it :( :');
+ console.warn(payload);
}
} else {
console.warn('webkit-devtools-agent: Unrecognized ' +
- 'message type received by DebuggerAgent: ' + payload);
+ 'message type received by DebuggerAgent: ');
+ console.warn(payload);
}
+ };
+ /**
+ * Callback function to received debug data coming out of
+ * the debugee process.
+ *
+ * @param {Buffer} data Data sent by v8 debug agent
+ * @api private
+ */
+ this.onData = function(data) {
+ this.protocol.execute(data);
};
/**
@@ -132,13 +127,15 @@ var DebuggerClient = module.exports = function(notify) {
}
var queue = this.queue;
-
for (var i = 0, len = queue.length; i < len; i++) {
- var message = queue[i];
+ var message = JSON.stringify(queue[i]);
+
this.connection.write('Content-Length: ' +
message.length + '\r\n\r\n' + message)
- }
+ //removes message from the queue
+ queue.splice(i, 1);
+ }
};
/**
@@ -175,7 +172,7 @@ var DebuggerClient = module.exports = function(notify) {
if (this.queue.length > 50) {
console.warn('webkit-devtools-agent: Debugger client ' +
- 'queue is too big. The client was unable ' +
+ 'queue is too big. It could mean that the client was unable ' +
'to establish a connection with the v8 debug agent. ' +
'Restart the agent and start your debugging session again.');
}
@@ -190,6 +187,9 @@ var DebuggerClient = module.exports = function(notify) {
* @api public
*/
this.connect = function(callback) {
+ this.protocol = new V8Protocol();
+ this.protocol.onResponse = this.onV8Response.bind(this);
+
this.connection = net.connect(this.port);
this.connection.setEncoding('utf8');
@@ -218,6 +218,10 @@ var DebuggerClient = module.exports = function(notify) {
* `uncaught` exceptions or no exceptions.
* Initial pause on exceptions state is none.
*
+ * Gotcha: V8 remote debugger protocol doesn't understand `none` as
+ * break type, so we need to send `uncaught` and `enabled` equaling false
+ * to represent `none`.
+ *
* @param {String} exceptionBreak Type of exception break
* it can be `all` or `uncaught`.
* @param {Function} callback Callback function to send back
@@ -231,12 +235,30 @@ var DebuggerClient = module.exports = function(notify) {
type: 'request',
command: 'setexceptionbreak',
arguments: {
- type: exceptionBreak,
- enabled: true
+ type: exceptionBreak === 'none' ? 'uncaught': exceptionBreak,
+ enabled: exceptionBreak == 'none' ? false : true
}
};
this.send(request, callback);
};
+
+ this.getScripts = function() {
+ var self = this;
+ var request = {
+ type: 'request',
+ command: 'scripts',
+ arguments: {
+ types: 4, //normal scripts
+ includeSource: true
+ }
+ };
+
+ this.send(request, function(scripts) {
+ for (var i = 0, len = scripts.length; i < len; i++) {
+ self.notify(scripts[i]);
+ }
+ });
+ };
}).call(DebuggerClient.prototype);
View
@@ -59,7 +59,7 @@ var DebuggerAgent = module.exports = function(debuggee) {
setTimeout(function() {
self.client.connect(function(data) {
- sendResult(data);
+ self.client.getScripts();
self.enabled = true;
});
}, 1000);
View
@@ -4,7 +4,7 @@
* to https://developers.google.com/chrome-developer-tools/docs/protocol/1.0
**/
-var formatScript = function(script) {
+/*var formatScript = function(script) {
var lineEnds = script.line_ends;
var lineCount = lineEnds.length;
var endLine = script.line_offset + lineCount - 1;
@@ -30,6 +30,32 @@ var formatScript = function(script) {
endColumn: endColumn,
isContentScript: !!script.context_data && script.context_data.indexOf("injected") == 0
};
+};*/
+
+var formatScript = function(script) {
+ var endLine = script.lineOffset + script.lineCount - 1;
+ var endColumn = 0;
+
+ // V8 will not count last line if script source ends with \n.
+ if (script.source[script.sourceLength - 1] === '\n') {
+ endLine += 1;
+ } else {
+ if (script.lineCount === 1) {
+ endColumn = script.sourceLength + script.columnOffset;
+ } else {
+ endColumn = script.sourceLength - (script.source[script.lineCount - 2].length);
+ }
+ }
+
+ return {
+ scriptId: script.id.toString(),
+ url: script.name,
+ startLine: script.lineOffset,
+ startColumn: script.columnOffset,
+ endLine: endLine,
+ endColumn: endColumn,
+ isContentScript: false
+ };
};
module.exports = {
@@ -45,7 +71,31 @@ module.exports = {
};
},
+ scripts: function(response) {
+ var scripts = [];
+ var scripts_ = response.body;
+
+ for (var i = 0, len = scripts_.length; i < len; i++) {
+ var script = scripts_[i];
+
+ scripts.push({
+ method: 'Debugger.scriptParsed',
+ params: formatScript(script)
+ });
+ }
+
+ return scripts;
+ },
+
+ /**
+ * Naming exceptions in order to translate the v8 protocol
+ * dynamicaly, based on the field `command` of
+ */
setexceptionbreak: function(response) {
return {};
+ },
+
+ scriptCollected: function(script) {
+ console.log(script);
}
};

0 comments on commit 3b2485b

Please sign in to comment.