Skip to content

Commit a2ea168

Browse files
JacksonTianbnoordhuis
authored andcommitted
debugger: don't spawn child process in remote mode
When debug in remote mode with host:port or pid, the interface spawn child process also. If the debugger agent is running, will get following output: ``` < Error: listen EADDRINUSE :::5858 < at Object.exports._errnoException (util.js:734:11) < at exports._exceptionWithHostPort (util.js:757:20) < at Agent.Server._listen2 (net.js:1155:14) < at listen (net.js:1181:10) < at Agent.Server.listen (net.js:1268:5) < at Object.start (_debug_agent.js:21:9) < at startup (node.js:68:9) < at node.js:799:3 ``` This fix won't spawn child process and no more error message was shown. When use `iojs debug`, the tip information just like this: ``` Usage: iojs debug script.js ``` This fix will display the advance usage also: ``` Usage: iojs debug script.js iojs debug <host>:<port> iojs debug -p <pid> ``` Fixes: #889 PR-URL: #1282 Reviewed-By: Ben Noordhuis <[email protected]>
1 parent 955c150 commit a2ea168

File tree

2 files changed

+73
-20
lines changed

2 files changed

+73
-20
lines changed

lib/_debugger.js

+21-20
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ exports.start = function(argv, stdin, stdout) {
1515

1616
if (argv.length < 1) {
1717
console.error('Usage: iojs debug script.js');
18+
console.error(' iojs debug <host>:<port>');
19+
console.error(' iojs debug -p <pid>');
1820
process.exit(1);
1921
}
2022

@@ -1626,6 +1628,7 @@ Interface.prototype.trySpawn = function(cb) {
16261628
this.killChild();
16271629
assert(!this.child);
16281630

1631+
var isRemote = false;
16291632
if (this.args.length === 2) {
16301633
var match = this.args[1].match(/^([^:]+):(\d+)$/);
16311634

@@ -1634,21 +1637,13 @@ Interface.prototype.trySpawn = function(cb) {
16341637
// `node debug localhost:5858`
16351638
host = match[1];
16361639
port = parseInt(match[2], 10);
1637-
this.child = {
1638-
kill: function() {
1639-
// TODO Do we really need to handle it?
1640-
}
1641-
};
1640+
isRemote = true;
16421641
}
16431642
} else if (this.args.length === 3) {
16441643
// `node debug -p pid`
16451644
if (this.args[1] === '-p' && /^\d+$/.test(this.args[2])) {
1646-
this.child = {
1647-
kill: function() {
1648-
// TODO Do we really need to handle it?
1649-
}
1650-
};
16511645
process._debugProcess(parseInt(this.args[2], 10));
1646+
isRemote = true;
16521647
} else {
16531648
var match = this.args[1].match(/^--port=(\d+)$/);
16541649
if (match) {
@@ -1660,10 +1655,13 @@ Interface.prototype.trySpawn = function(cb) {
16601655
}
16611656
}
16621657

1663-
this.child = spawn(process.execPath, childArgs);
1658+
if (!isRemote) {
1659+
// pipe stream into debugger
1660+
this.child = spawn(process.execPath, childArgs);
16641661

1665-
this.child.stdout.on('data', this.childPrint.bind(this));
1666-
this.child.stderr.on('data', this.childPrint.bind(this));
1662+
this.child.stdout.on('data', this.childPrint.bind(this));
1663+
this.child.stderr.on('data', this.childPrint.bind(this));
1664+
}
16671665

16681666
this.pause();
16691667

@@ -1707,9 +1705,10 @@ Interface.prototype.trySpawn = function(cb) {
17071705

17081706
client.on('error', connectError);
17091707
function connectError() {
1710-
// If it's failed to connect 4 times then don't catch the next error
1708+
// If it's failed to connect 10 times then print failed message
17111709
if (connectionAttempts >= 10) {
1712-
client.removeListener('error', connectError);
1710+
self.stdout.write(' failed, please retry\n');
1711+
return;
17131712
}
17141713
setTimeout(attemptConnect, 500);
17151714
}
@@ -1720,10 +1719,12 @@ Interface.prototype.trySpawn = function(cb) {
17201719
client.connect(port, host);
17211720
}
17221721

1723-
this.child.stderr.once('data', function() {
1724-
setImmediate(function() {
1725-
self.print('connecting to port ' + port + '..', true);
1726-
attemptConnect();
1722+
self.print('connecting to ' + host + ':' + port + ' ..', true);
1723+
if (isRemote) {
1724+
attemptConnect();
1725+
} else {
1726+
this.child.stderr.once('data', function() {
1727+
setImmediate(attemptConnect);
17271728
});
1728-
});
1729+
}
17291730
};

test/debugger/test-debugger-remote.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
var common = require('../common');
2+
var assert = require('assert');
3+
var spawn = require('child_process').spawn;
4+
5+
var port = common.PORT + 1337;
6+
var buffer = '';
7+
var expected = [];
8+
var scriptToDebug = common.fixturesDir + '/empty.js';
9+
10+
function fail() {
11+
assert(0); // `iojs --debug-brk script.js` should not quit
12+
}
13+
14+
// running with debug agent
15+
var child = spawn(process.execPath, ['--debug-brk=5959', scriptToDebug]);
16+
17+
console.error(process.execPath, '--debug-brk=5959', scriptToDebug);
18+
19+
// connect to debug agent
20+
var interfacer = spawn(process.execPath, ['debug', 'localhost:5959']);
21+
22+
console.error(process.execPath, 'debug', 'localhost:5959');
23+
interfacer.stdout.setEncoding('utf-8');
24+
interfacer.stdout.on('data', function(data) {
25+
data = (buffer + data).split('\n');
26+
buffer = data.pop();
27+
data.forEach(function(line) {
28+
interfacer.emit('line', line);
29+
});
30+
});
31+
32+
interfacer.on('line', function(line) {
33+
line = line.replace(/^(debug> *)+/, '');
34+
console.log(line);
35+
var expected = '\bconnecting to localhost:5959 ... ok';
36+
assert.ok(expected == line, 'Got unexpected line: ' + line);
37+
});
38+
39+
// give iojs time to start up the debugger
40+
setTimeout(function() {
41+
child.removeListener('exit', fail);
42+
child.kill();
43+
interfacer.removeListener('exit', fail);
44+
interfacer.kill();
45+
}, 2000);
46+
47+
process.on('exit', function() {
48+
assert(child.killed);
49+
assert(interfacer.killed);
50+
});
51+
52+
interfacer.stderr.pipe(process.stderr);

0 commit comments

Comments
 (0)