Skip to content

Commit 4891001

Browse files
bnoordhuisFishrock123
authored andcommitted
debugger: make listen address configurable
`--debug=1.2.3.4:5678` and `--debug=example.com:5678` are now accepted, likewise the `--debug-brk` and `--debug-port` switch. The latter is now something of a misnomer but it's undocumented and for internal use only so it shouldn't matter too much. `--inspect=1.2.3.4:5678` and `--inspect=example.com:5678` are also accepted but don't use the host name yet; they still bind to the default address. Fixes: #3306 PR-URL: #3316 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com>
1 parent 1bd6a62 commit 4891001

10 files changed

Lines changed: 128 additions & 48 deletions

‎lib/_debug_agent.js‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ exports.start = function start() {
1818
process._rawDebug(err.stack||err);
1919
});
2020

21-
agent.listen(process._debugAPI.port,function(){
22-
varaddr=this.address();
23-
process._rawDebug('Debugger listening on port %d',addr.port);
21+
agent.listen(process._debugAPI.port,process._debugAPI.host,function(){
22+
constaddr=this.address();
23+
consthost=net.isIPv6(addr.address) ? `[${addr.address}]` : addr.address;
24+
process._rawDebug('Debugger listening on %s:%d',host,addr.port);
2425
process._debugAPI.notifyListen();
2526
});
2627

‎src/debug-agent.cc‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ using v8::Integer;
4444
using v8::Isolate;
4545
using v8::Local;
4646
using v8::Locker;
47+
using v8::NewStringType;
4748
using v8::Object;
4849
using v8::String;
4950
using v8::Value;
@@ -69,7 +70,7 @@ Agent::~Agent() {
6970
}
7071

7172

72-
boolAgent::Start(int port, bool wait) {
73+
boolAgent::Start(const std::string& host, int port, bool wait) {
7374
int err;
7475

7576
if (state_ == kRunning)
@@ -85,6 +86,7 @@ bool Agent::Start(int port, bool wait) {
8586
goto async_init_failed;
8687
uv_unref(reinterpret_cast<uv_handle_t*>(&child_signal_));
8788

89+
host_ = host;
8890
port_ = port;
8991
wait_ = wait;
9092

@@ -213,6 +215,10 @@ void Agent::InitAdaptor(Environment* env) {
213215
t->GetFunction()->NewInstance(env->context()).ToLocalChecked();
214216
api->SetAlignedPointerInInternalField(0, this);
215217

218+
api->Set(String::NewFromUtf8(isolate, "host",
219+
NewStringType::kNormal).ToLocalChecked(),
220+
String::NewFromUtf8(isolate, host_.data(), NewStringType::kNormal,
221+
host_.size()).ToLocalChecked());
216222
api->Set(String::NewFromUtf8(isolate, "port"), Integer::New(isolate, port_));
217223

218224
env->process_object()->Set(String::NewFromUtf8(isolate, "_debugAPI"), api);

‎src/debug-agent.h‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include"v8-debug.h"
3333

3434
#include<string.h>
35+
#include<string>
3536

3637
// Forward declaration to break recursive dependency chain with src/env.h.
3738
namespacenode {
@@ -75,7 +76,7 @@ class Agent {
7576
typedefvoid (*DispatchHandler)(node::Environment* env);
7677

7778
// Start the debugger agent thread
78-
boolStart(int port, bool wait);
79+
boolStart(const std::string& host, int port, bool wait);
7980
// Listen for debug events
8081
voidEnable();
8182
// Stop the debugger agent
@@ -114,6 +115,7 @@ class Agent {
114115

115116
State state_;
116117

118+
std::string host_;
117119
int port_;
118120
bool wait_;
119121

‎src/node.cc‎

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858
#include<stdlib.h>
5959
#include<string.h>
6060
#include<sys/types.h>
61+
62+
#include<string>
6163
#include<vector>
6264

6365
#if defined(NODE_HAVE_I18N_SUPPORT)
@@ -141,10 +143,14 @@ static unsigned int preload_module_count = 0;
141143
staticconstchar** preload_modules = nullptr;
142144
#if HAVE_INSPECTOR
143145
staticbool use_inspector = false;
146+
#else
147+
staticconstbool use_inspector = false;
144148
#endif
145149
staticbool use_debug_agent = false;
146150
staticbool debug_wait_connect = false;
151+
static std::string debug_host; // NOLINT(runtime/string)
147152
staticint debug_port = 5858;
153+
static std::string inspector_host; // NOLINT(runtime/string)
148154
staticint inspector_port = 9229;
149155
staticconstint v8_default_thread_pool_size = 4;
150156
staticint v8_thread_pool_size = v8_default_thread_pool_size;
@@ -203,23 +209,20 @@ static struct {
203209
platform_ = nullptr;
204210
}
205211

206-
#if HAVE_INSPECTOR
207212
voidStartInspector(Environment *env, int port, bool wait) {
213+
#if HAVE_INSPECTOR
208214
env->inspector_agent()->Start(platform_, port, wait);
209-
}
210215
#endif// HAVE_INSPECTOR
216+
}
211217

212218
v8::Platform* platform_;
213219
#else// !NODE_USE_V8_PLATFORM
214220
voidInitialize(int thread_pool_size) {}
215221
voidPumpMessageLoop(Isolate* isolate) {}
216222
voidDispose() {}
217-
#if HAVE_INSPECTOR
218223
voidStartInspector(Environment *env, int port, bool wait) {
219224
env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
220225
}
221-
#endif// HAVE_INSPECTOR
222-
223226
#endif// !NODE_USE_V8_PLATFORM
224227
} v8_platform;
225228

@@ -3514,6 +3517,7 @@ static bool ParseDebugOpt(const char* arg) {
35143517
debug_wait_connect = true;
35153518
port = arg + sizeof("--debug-brk=") - 1;
35163519
} elseif (!strncmp(arg, "--debug-port=", sizeof("--debug-port=") - 1)) {
3520+
// XXX(bnoordhuis) Misnomer, configures port and listen address.
35173521
port = arg + sizeof("--debug-port=") - 1;
35183522
#if HAVE_INSPECTOR
35193523
// Specifying both --inspect and --debug means debugging is on, using Chromium
@@ -3535,24 +3539,49 @@ static bool ParseDebugOpt(const char* arg) {
35353539
returnfalse;
35363540
}
35373541

3538-
if (port != nullptr) {
3539-
int port_int = atoi(port);
3540-
if (port_int < 1024 || port_int > 65535) {
3541-
fprintf(stderr, "Debug port must be in range 1024 to 65535.\n");
3542-
PrintHelp();
3543-
exit(12);
3544-
}
3545-
#if HAVE_INSPECTOR
3546-
if (use_inspector) {
3547-
inspector_port = port_int;
3548-
} else {
3549-
#endif
3550-
debug_port = port_int;
3551-
#if HAVE_INSPECTOR
3542+
if (port == nullptr) {
3543+
returntrue;
3544+
}
3545+
3546+
std::string* const the_host = use_inspector ? &inspector_host : &debug_host;
3547+
int* const the_port = use_inspector ? &inspector_port : &debug_port;
3548+
3549+
// FIXME(bnoordhuis) Move IPv6 address parsing logic to lib/net.js.
3550+
// It seems reasonable to support [address]:port notation
3551+
// in net.Server#listen() and net.Socket#connect().
3552+
constsize_t port_len = strlen(port);
3553+
if (port[0] == '[' && port[port_len - 1] == ']') {
3554+
the_host->assign(port + 1, port_len - 2);
3555+
returntrue;
3556+
}
3557+
3558+
constchar* const colon = strrchr(port, ':');
3559+
if (colon == nullptr) {
3560+
// Either a port number or a host name. Assume that
3561+
// if it's not all decimal digits, it's a host name.
3562+
for (size_t n = 0; port[n] != '\0'; n += 1) {
3563+
if (port[n] < '0' || port[n] > '9') {
3564+
*the_host = port;
3565+
returntrue;
3566+
}
35523567
}
3553-
#endif
3568+
} else {
3569+
constbool skip = (colon > port && port[0] == '[' && colon[-1] == ']');
3570+
the_host->assign(port + skip, colon - skip);
3571+
}
3572+
3573+
char* endptr;
3574+
errno = 0;
3575+
constchar* const digits = colon != nullptr ? colon + 1 : port;
3576+
constlong result = strtol(digits, &endptr, 10); // NOLINT(runtime/int)
3577+
if (errno != 0 || *endptr != '\0' || result < 1024 || result > 65535) {
3578+
fprintf(stderr, "Debug port must be in range 1024 to 65535.\n");
3579+
PrintHelp();
3580+
exit(12);
35543581
}
35553582

3583+
*the_port = static_cast<int>(result);
3584+
35563585
returntrue;
35573586
}
35583587

@@ -3810,34 +3839,31 @@ static void DispatchMessagesDebugAgentCallback(Environment* env) {
38103839

38113840
staticvoidStartDebug(Environment* env, bool wait) {
38123841
CHECK(!debugger_running);
3813-
#if HAVE_INSPECTOR
38143842
if (use_inspector) {
38153843
v8_platform.StartInspector(env, inspector_port, wait);
38163844
debugger_running = true;
38173845
} else {
3818-
#endif
38193846
env->debugger_agent()->set_dispatch_handler(
38203847
DispatchMessagesDebugAgentCallback);
3821-
debugger_running = env->debugger_agent()->Start(debug_port, wait);
3848+
debugger_running =
3849+
env->debugger_agent()->Start(debug_host, debug_port, wait);
38223850
if (debugger_running == false) {
3823-
fprintf(stderr, "Starting debugger on port %d failed\n", debug_port);
3851+
fprintf(stderr, "Starting debugger on %s:%d failed\n",
3852+
debug_host.c_str(), debug_port);
38243853
fflush(stderr);
38253854
return;
38263855
}
3827-
#if HAVE_INSPECTOR
38283856
}
3829-
#endif
38303857
}
38313858

38323859

38333860
// Called from the main thread.
38343861
staticvoidEnableDebug(Environment* env) {
38353862
CHECK(debugger_running);
3836-
#if HAVE_INSPECTOR
3863+
38373864
if (use_inspector) {
38383865
return;
38393866
}
3840-
#endif
38413867

38423868
// Send message to enable debug in workers
38433869
HandleScope handle_scope(env->isolate());

‎test/parallel/test-cluster-disconnect-handles.js‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,8 @@ cluster.schedulingPolicy = cluster.SCHED_RR;
2525
if(cluster.isMaster){
2626
letisKilling=false;
2727
consthandles=require('internal/cluster').handles;
28-
// FIXME(bnoordhuis) lib/cluster.js scans the execArgv arguments for
29-
// debugger flags and renumbers any port numbers it sees starting
30-
// from the default port 5858. Add a '.' that circumvents the
31-
// scanner but is ignored by atoi(3). Heinous hack.
32-
cluster.setupMaster({execArgv: [`--debug=${common.PORT}.`]});
28+
constaddress=common.hasIPv6 ? '[::1]' : common.localhostIPv4;
29+
cluster.setupMaster({execArgv: [`--debug=${address}:${common.PORT}`]});
3330
constworker=cluster.fork();
3431
worker.once('exit',common.mustCall((code,signal)=>{
3532
assert.strictEqual(code,0,'worker did not exit normally');

‎test/parallel/test-debug-port-cluster.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ child.stderr.setEncoding('utf8');
1616

1717
constcheckMessages=common.mustCall(()=>{
1818
for(letport=PORT_MIN;port<=PORT_MAX;port+=1){
19-
assert(stderr.includes(`Debugger listening on port ${port}`));
19+
constre=RegExp(`Debugger listening on (\\[::\\]|0\\.0\\.0\\.0):${port}`);
20+
assert(re.test(stderr));
2021
}
2122
});
2223

‎test/parallel/test-debug-port-from-cmdline.js‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,10 @@ function processStderrLine(line) {
3939
functionassertOutputLines(){
4040
varexpectedLines=[
4141
'Starting debugger agent.',
42-
'Debugger listening on port '+debugPort
42+
'Debugger listening on (\\[::\\]|0\\.0\\.0\\.0):'+debugPort,
4343
];
4444

4545
assert.equal(outputLines.length,expectedLines.length);
4646
for(vari=0;i<expectedLines.length;i++)
47-
assert.equal(outputLines[i],expectedLines[i]);
48-
47+
assert(RegExp(expectedLines[i]).test(outputLines[i]));
4948
}

‎test/parallel/test-debug-port-numbers.js‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ function kill(child) {
5252

5353
process.on('exit',function(){
5454
for(constchildofchildren){
55-
constone=RegExp(`Debugger listening on port ${child.test.port}`);
56-
consttwo=RegExp(`connecting to 127.0.0.1:${child.test.port}`);
55+
constport=child.test.port;
56+
constone=RegExp(`Debugger listening on (\\[::\\]|0\.0\.0\.0):${port}`);
57+
consttwo=RegExp(`connecting to 127.0.0.1:${port}`);
5758
assert(one.test(child.test.stdout));
5859
assert(two.test(child.test.stdout));
5960
}

‎test/parallel/test-debug-signal-cluster.js‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ process.on('exit', function onExit() {
6363

6464
varexpectedLines=[
6565
'Starting debugger agent.',
66-
'Debugger listening on port '+(port+0),
66+
'Debugger listening on (\\[::\\]|0\\.0\\.0\\.0):'+(port+0),
6767
'Starting debugger agent.',
68-
'Debugger listening on port '+(port+1),
68+
'Debugger listening on (\\[::\\]|0\\.0\\.0\\.0):'+(port+1),
6969
'Starting debugger agent.',
70-
'Debugger listening on port '+(port+2),
70+
'Debugger listening on (\\[::\\]|0\\.0\\.0\\.0):'+(port+2),
7171
];
7272

7373
functionassertOutputLines(){
@@ -79,5 +79,5 @@ function assertOutputLines() {
7979

8080
assert.equal(outputLines.length,expectedLines.length);
8181
for(vari=0;i<expectedLines.length;i++)
82-
assert.equal(outputLines[i],expectedLines[i]);
82+
assert(RegExp(expectedLines[i]).test(outputLines[i]));
8383
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constassert=require('assert');
5+
constspawn=require('child_process').spawn;
6+
7+
letrun=()=>{};
8+
functiontest(args,re){
9+
constnext=run;
10+
run=()=>{
11+
constoptions={encoding: 'utf8'};
12+
constproc=spawn(process.execPath,args.concat(['-e','0']),options);
13+
letstderr='';
14+
proc.stderr.setEncoding('utf8');
15+
proc.stderr.on('data',(data)=>{
16+
stderr+=data;
17+
if(re.test(stderr))proc.kill();
18+
});
19+
proc.on('exit',common.mustCall(()=>{
20+
assert(re.test(stderr));
21+
next();
22+
}));
23+
};
24+
}
25+
26+
test(['--debug-brk'],/Debuggerlisteningon(\[::\]|0\.0\.0\.0):5858/);
27+
test(['--debug-brk=1234'],/Debuggerlisteningon(\[::\]|0\.0\.0\.0):1234/);
28+
test(['--debug-brk=127.0.0.1'],/Debuggerlisteningon127\.0\.0\.1:5858/);
29+
test(['--debug-brk=127.0.0.1:1234'],/Debuggerlisteningon127\.0\.0\.1:1234/);
30+
test(['--debug-brk=localhost'],
31+
/Debuggerlisteningon(\[::\]|127\.0\.0\.1):5858/);
32+
test(['--debug-brk=localhost:1234'],
33+
/Debuggerlisteningon(\[::\]|127\.0\.0\.1):1234/);
34+
35+
if(common.hasIPv6){
36+
test(['--debug-brk=::'],/Debugportmustbeinrange1024to65535/);
37+
test(['--debug-brk=::0'],/Debugportmustbeinrange1024to65535/);
38+
test(['--debug-brk=::1'],/Debugportmustbeinrange1024to65535/);
39+
test(['--debug-brk=[::]'],/Debuggerlisteningon\[::\]:5858/);
40+
test(['--debug-brk=[::0]'],/Debuggerlisteningon\[::\]:5858/);
41+
test(['--debug-brk=[::]:1234'],/Debuggerlisteningon\[::\]:1234/);
42+
test(['--debug-brk=[::0]:1234'],/Debuggerlisteningon\[::\]:1234/);
43+
test(['--debug-brk=[::ffff:127.0.0.1]:1234'],
44+
/Debuggerlisteningon\[::ffff:127\.0\.0\.1\]:1234/);
45+
}
46+
47+
run();// Runs tests in reverse order.

0 commit comments

Comments
 (0)