more cli options
authorFedor Indutny <fedor.indutny@gmail.com>
Sat, 24 Sep 2011 05:44:08 +0000 (12:44 +0700)
committerRyan Dahl <ry@tinyclouds.org>
Sun, 25 Sep 2011 18:58:22 +0000 (11:58 -0700)
* node debug localhost:5858 - connects to remote debugger
* node debug -p `pgrep node` - connects to running process
* Fixed double-run of debugger on SIGUSR1

lib/_debugger.js
src/node.cc

index 9275fb5..4e3c9b2 100644 (file)
@@ -27,8 +27,6 @@ var util = require('util'),
     inherits = util.inherits,
     spawn = require('child_process').spawn;
 
-exports.port = 5858;
-
 exports.start = function(argv, stdin, stdout) {
   argv || (argv = process.argv.slice(2));
 
@@ -922,6 +920,8 @@ Interface.prototype.controlEval = function(code, context, filename, callback) {
 
 // Used for debugger's remote evaluation (`repl`) commands
 Interface.prototype.debugEval = function(code, context, filename, callback) {
+  if (!this.requireConnection()) return;
+
   var self = this,
       client = this.client;
 
@@ -1409,14 +1409,43 @@ Interface.prototype.killChild = function() {
 // Spawns child process (and restores breakpoints)
 Interface.prototype.trySpawn = function(cb) {
   var self = this,
-      breakpoints = this.breakpoints || [];
+      breakpoints = this.breakpoints || [],
+      port = 5858,
+      host = 'localhost';
 
   this.killChild();
 
-  this.child = spawn(process.execPath, this.args);
+  // Connecting to remote debugger
+  // `node debug localhost:5858`
+  if (this.args.length === 2) {
+    var match = this.args[1].match(/^([^:]+):(\d+)$/);
+    if (match) {
+      host = match[1];
+      port = parseInt(match[2], 10);
+      this.child = {
+        kill: function() {
+          // TODO Do we really need to handle it?
+        }
+      };
+    }
+  } else if (this.args.length === 3) {
+    // `node debug -p pid`
+    if (this.args[1] === '-p' && /^\d+$/.test(this.args[2])) {
+      this.child = {
+        kill: function() {
+          // TODO Do we really need to handle it?
+        }
+      };
+      process.kill(parseInt(this.args[2], 10), 'SIGUSR1');
+    }
+  }
+
+  if (!this.child) {
+    this.child = spawn(process.execPath, this.args);
 
-  this.child.stdout.on('data', this.childPrint.bind(this));
-  this.child.stderr.on('data', this.childPrint.bind(this));
+    this.child.stdout.on('data', this.childPrint.bind(this));
+    this.child.stderr.on('data', this.childPrint.bind(this));
+  }
 
   this.pause();
 
@@ -1461,16 +1490,16 @@ Interface.prototype.trySpawn = function(cb) {
   client.on('error', connectError);
   function connectError() {
     // If it's failed to connect 4 times then don't catch the next error
-    if (connectionAttempts >= 4) {
+    if (connectionAttempts >= 10) {
       client.removeListener('error', connectError);
     }
-    setTimeout(attemptConnect, 50);
+    setTimeout(attemptConnect, 500);
   }
 
   function attemptConnect() {
     ++connectionAttempts;
     self.stdout.write('.');
-    client.connect(exports.port);
+    client.connect(port, host);
   }
 
   setTimeout(function() {
index 336240a..1cd6bc0 100644 (file)
@@ -2356,14 +2356,17 @@ static void EnableDebug(bool wait_connect) {
 
   // Print out some information.
   fprintf(stderr, "debugger listening on port %d", debug_port);
+
+  debugger_running = true;
 }
 
 
 static volatile bool hit_signal;
+static volatile bool debugger_running = false;
 
 
 static void DebugSignalCB(const Debug::EventDetails& details) {
-  if (hit_signal && details.GetEvent() == v8::Break) {
+  if (!debugger_running && hit_signal && details.GetEvent() == v8::Break) {
     hit_signal = false;
     fprintf(stderr, "Hit SIGUSR1 - starting debugger agent.\n");
     EnableDebug(false);