From 32f4c18c3ce44881c4bcef63cc65fb9c045a1316 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 8 Jun 2018 10:23:18 -0700 Subject: [PATCH 1/4] tools,gyp: fix regex for version matching Tool versions can be 10 and higher. Float patch from node-gyp to accommodate this fact of life. PR-URL: https://github.com/nodejs/node/pull/21216 Refs: https://github.com/nodejs/node-gyp/commit/293092c362febffe19f72712467565045e08e8f1 Reviewed-By: Refael Ackermann Reviewed-By: Ben Noordhuis Reviewed-By: Richard Lau Reviewed-By: Anna Henningsen --- tools/gyp/pylib/gyp/xcode_emulation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gyp/pylib/gyp/xcode_emulation.py b/tools/gyp/pylib/gyp/xcode_emulation.py index 407ead074bbe7e..5ae81ea2935570 100644 --- a/tools/gyp/pylib/gyp/xcode_emulation.py +++ b/tools/gyp/pylib/gyp/xcode_emulation.py @@ -1262,7 +1262,7 @@ def XcodeVersion(): except: version = CLTVersion() if version: - version = re.match(r'(\d\.\d\.?\d*)', version).groups()[0] + version = re.match(r'(\d+\.\d+\.?\d*)', version).groups()[0] else: raise GypError("No Xcode or CLT version detected!") # The CLT has no build information, so we return an empty string. From 56bf7fd079e9c4e6e626c14972b8c3cc3a8785b0 Mon Sep 17 00:00:00 2001 From: Misty De Meo Date: Wed, 6 Jun 2018 12:28:42 -0700 Subject: [PATCH 2/4] build: fix configure script for double-digits Compare versions using tuples instead of strings so that it is future-proofed against versions that contain a number that is more than one digit. Backport-PR-URL: https://github.com/nodejs/node/pull/21301 PR-URL: https://github.com/nodejs/node/pull/21183 Reviewed-By: Richard Lau Reviewed-By: Rich Trott Reviewed-By: Joyee Cheung Reviewed-By: Jeremiah Senkpiel Reviewed-By: Trivikram Kamat --- configure | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure b/configure index dd72cc332436a2..c5650a3ae20eca 100755 --- a/configure +++ b/configure @@ -572,8 +572,8 @@ def try_check_compiler(cc, lang): values = (proc.communicate()[0].split() + ['0'] * 7)[0:7] is_clang = values[0] == '1' - gcc_version = '%s.%s.%s' % tuple(values[1:1+3]) - clang_version = '%s.%s.%s' % tuple(values[4:4+3]) + gcc_version = tuple(values[1:1+3]) + clang_version = tuple(values[4:4+3]) return (True, is_clang, clang_version, gcc_version) @@ -647,13 +647,13 @@ def check_compiler(o): ok, is_clang, clang_version, gcc_version = try_check_compiler(CXX, 'c++') if not ok: warn('failed to autodetect C++ compiler version (CXX=%s)' % CXX) - elif clang_version < '3.4.2' if is_clang else gcc_version < '4.8.0': + elif clang_version < (3, 4, 2) if is_clang else gcc_version < (4, 8, 0): warn('C++ compiler too old, need g++ 4.8 or clang++ 3.4.2 (CXX=%s)' % CXX) ok, is_clang, clang_version, gcc_version = try_check_compiler(CC, 'c') if not ok: warn('failed to autodetect C compiler version (CC=%s)' % CC) - elif not is_clang and gcc_version < '4.2.0': + elif not is_clang and gcc_version < (4, 2, 0): # clang 3.2 is a little white lie because any clang version will probably # do for the C bits. However, we might as well encourage people to upgrade # to a version that is not completely ancient. From a5d1ab3c38e7b3e9130d85f1905f5b7439fc31f0 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 8 Jun 2018 09:48:48 -0700 Subject: [PATCH 3/4] =?UTF-8?q?tools:=20update=20tooling=20to=20work=20wit?= =?UTF-8?q?h=20new=20macOS=20CLI=20=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using High Sierra and `xcode-select --install` without installing full Xcode, our build tooling breaks due to faulty regular expressions. Update the `configure` script in our project root directory to handle multi-digit version numbers. `tools/gyp` and `deps/npm/node_modules/node-gyp` still need to be updated for a complete fix. PR-URL: https://github.com/nodejs/node/pull/21173 Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca Reviewed-By: Refael Ackermann Reviewed-By: James M Snell --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index c5650a3ae20eca..511cc12b25cccf 100755 --- a/configure +++ b/configure @@ -610,7 +610,7 @@ def get_llvm_version(cc): def get_xcode_version(cc): return get_version_helper( - cc, r"(^Apple LLVM version) ([5-9]\.[0-9]+)") + cc, r"(^Apple LLVM version) ([0-9]+\.[0-9]+)") def get_gas_version(cc): try: From bf5bef589d325d50060e712bf14b5a7f28b9d921 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 17 Jun 2018 10:54:56 +0200 Subject: [PATCH 4/4] inspector: don't bind to 0.0.0.0 by default Change the bind address from 0.0.0.0 to 127.0.0.1 and start respecting the address part of `--inspect=
:` so that the bind address can be overridden by the user. Fixes: https://github.com/nodejs/node/issues/21349 --- src/inspector_agent.cc | 52 +++++++++++++++-------- src/inspector_agent.h | 3 +- src/node.cc | 12 +++--- test/inspector/inspector-helper.js | 2 +- test/sequential/test-inspector-address.js | 44 +++++++++++++++++++ 5 files changed, 88 insertions(+), 25 deletions(-) create mode 100644 test/sequential/test-inspector-address.js diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index f7141f6f8021c7..f682af90236060 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -37,20 +37,30 @@ static const uint8_t PROTOCOL_JSON[] = { #include "v8_inspector_protocol_json.h" // NOLINT(build/include_order) }; -std::string GetWsUrl(int port, const std::string& id) { +std::string GetWsUrl(const sockaddr_in& address, const std::string& id) { char buf[1024]; - snprintf(buf, sizeof(buf), "127.0.0.1:%d/%s", port, id.c_str()); + char name[64]; + + if (uv_ip4_name(&address, name, sizeof(name))) *name = '\0'; + const int port = ntohs(address.sin_port); + snprintf(buf, sizeof(buf), "%s:%d/%s", name, port, id.c_str()); + return buf; } -void PrintDebuggerReadyMessage(int port, const std::string& id) { - fprintf(stderr, "Debugger listening on port %d.\n" +void PrintDebuggerReadyMessage(const sockaddr_in& address, + const std::string& id) { + const std::string ws_url = GetWsUrl(address, id); + const size_t slash_pos = ws_url.find('/'); + CHECK_NE(slash_pos, std::string::npos); + + fprintf(stderr, "Debugger listening on %.*s.\n" "Warning: This is an experimental feature and could change at any time.\n" "To start debugging, open the following URL in Chrome:\n" " chrome-devtools://devtools/remote/serve_file/" "@" V8_INSPECTOR_REVISION "/inspector.html?" "experiments=true&v8only=true&ws=%s\n", - port, GetWsUrl(port, id).c_str()); + static_cast(slash_pos), ws_url.c_str(), ws_url.c_str()); fflush(stderr); } @@ -187,7 +197,8 @@ class AgentImpl { ~AgentImpl(); // Start the inspector agent thread - bool Start(v8::Platform* platform, const char* path, int port, bool wait); + bool Start(v8::Platform* platform, const char* path, + const char* host, int port, bool wait); // Stop the inspector agent void Stop(); @@ -234,7 +245,7 @@ class AgentImpl { uv_thread_t thread_; uv_loop_t child_loop_; - int port_; + struct sockaddr_in saddr_; bool wait_; bool shutting_down_; State state_; @@ -380,7 +391,7 @@ class V8NodeInspector : public v8_inspector::V8InspectorClient { std::unique_ptr session_; }; -AgentImpl::AgentImpl(Environment* env) : port_(0), +AgentImpl::AgentImpl(Environment* env) : saddr_(), wait_(false), shutting_down_(false), state_(State::kNew), @@ -473,7 +484,10 @@ void InspectorWrapConsoleCall(const v8::FunctionCallbackInfo& args) { } bool AgentImpl::Start(v8::Platform* platform, const char* path, - int port, bool wait) { + const char* address, int port, bool wait) { + if (*address == '\0') address = "127.0.0.1"; + if (uv_ip4_addr(address, port, &saddr_)) return false; + auto env = parent_env_; inspector_ = new V8NodeInspector(this, env, platform); platform_ = platform; @@ -485,7 +499,6 @@ bool AgentImpl::Start(v8::Platform* platform, const char* path, int err = uv_loop_init(&child_loop_); CHECK_EQ(err, 0); - port_ = port; wait_ = wait; err = uv_thread_create(&thread_, AgentImpl::ThreadCbIO, this); @@ -661,7 +674,7 @@ void AgentImpl::SendListResponse(InspectorSocket* socket) { Escape(&response["url"]); if (!client_socket_) { - std::string address = GetWsUrl(port_, id_); + std::string address = GetWsUrl(saddr_, id_); std::ostringstream frontend_url; frontend_url << "https://chrome-devtools-frontend.appspot.com/serve_file/@"; @@ -715,7 +728,6 @@ void AgentImpl::WriteCbIO(uv_async_t* async) { } void AgentImpl::WorkerRunIO() { - sockaddr_in addr; uv_tcp_t server; int err = uv_loop_init(&child_loop_); CHECK_EQ(err, 0); @@ -729,14 +741,18 @@ void AgentImpl::WorkerRunIO() { uv_fs_req_cleanup(&req); } uv_tcp_init(&child_loop_, &server); - uv_ip4_addr("0.0.0.0", port_, &addr); server.data = this; err = uv_tcp_bind(&server, - reinterpret_cast(&addr), 0); + reinterpret_cast(&saddr_), 0); if (err == 0) { err = uv_listen(reinterpret_cast(&server), 1, OnSocketConnectionIO); } + if (err == 0) { + int namelen = sizeof(saddr_); + err = uv_tcp_getsockname(&server, reinterpret_cast(&saddr_), + &namelen); + } if (err != 0) { fprintf(stderr, "Unable to open devtools socket: %s\n", uv_strerror(err)); state_ = State::kError; // Safe, main thread is waiting on semaphore @@ -746,7 +762,7 @@ void AgentImpl::WorkerRunIO() { uv_sem_post(&start_sem_); return; } - PrintDebuggerReadyMessage(port_, id_); + PrintDebuggerReadyMessage(saddr_, id_); if (!wait_) { uv_sem_post(&start_sem_); } @@ -830,7 +846,7 @@ void AgentImpl::DispatchMessages() { if (shutting_down_) { state_ = State::kDone; } else { - PrintDebuggerReadyMessage(port_, id_); + PrintDebuggerReadyMessage(saddr_, id_); state_ = State::kAccepting; } inspector_->quitMessageLoopOnPause(); @@ -858,8 +874,8 @@ Agent::~Agent() { } bool Agent::Start(v8::Platform* platform, const char* path, - int port, bool wait) { - return impl->Start(platform, path, port, wait); + const char* host, int port, bool wait) { + return impl->Start(platform, path, host, port, wait); } void Agent::Stop() { diff --git a/src/inspector_agent.h b/src/inspector_agent.h index 3607cffba5d21f..3f576f2f3d54ab 100644 --- a/src/inspector_agent.h +++ b/src/inspector_agent.h @@ -29,7 +29,8 @@ class Agent { ~Agent(); // Start the inspector agent thread - bool Start(v8::Platform* platform, const char* path, int port, bool wait); + bool Start(v8::Platform* platform, const char* path, + const char* address, int port, bool wait); // Stop the inspector agent void Stop(); diff --git a/src/node.cc b/src/node.cc index 3f4c02413c9aa7..9c3bb1c55fd6a4 100644 --- a/src/node.cc +++ b/src/node.cc @@ -232,9 +232,10 @@ static struct { } bool StartInspector(Environment *env, const char* script_path, - int port, bool wait) { + const char* host, int port, bool wait) { #if HAVE_INSPECTOR - return env->inspector_agent()->Start(platform_, script_path, port, wait); + return env->inspector_agent()->Start(platform_, script_path, + host, port, wait); #else return true; #endif // HAVE_INSPECTOR @@ -246,7 +247,7 @@ static struct { void PumpMessageLoop(Isolate* isolate) {} void Dispose() {} bool StartInspector(Environment *env, const char* script_path, - int port, bool wait) { + const char* host, int port, bool wait) { env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0"); return false; // make compiler happy } @@ -4092,8 +4093,9 @@ static void DispatchMessagesDebugAgentCallback(Environment* env) { static void StartDebug(Environment* env, const char* path, bool wait) { CHECK(!debugger_running); if (use_inspector) { - debugger_running = v8_platform.StartInspector(env, path, inspector_port, - wait); + debugger_running = v8_platform.StartInspector(env, path, + inspector_host.c_str(), + inspector_port, wait); } else { env->debugger_agent()->set_dispatch_handler( DispatchMessagesDebugAgentCallback); diff --git a/test/inspector/inspector-helper.js b/test/inspector/inspector-helper.js index 7d1f4753b8b331..2c46cc9a191795 100644 --- a/test/inspector/inspector-helper.js +++ b/test/inspector/inspector-helper.js @@ -446,7 +446,7 @@ exports.startNodeForInspectorTest = function(callback) { clearTimeout(timeoutId); console.log('[err]', text); if (found) return; - const match = text.match(/Debugger listening on port (\d+)/); + const match = text.match(/Debugger listening on 127\.0\.0\.1:(\d+)\./); found = true; child.stderr.removeListener('data', dataCallback); assert.ok(match, text); diff --git a/test/sequential/test-inspector-address.js b/test/sequential/test-inspector-address.js new file mode 100644 index 00000000000000..e4a7c23305cb7d --- /dev/null +++ b/test/sequential/test-inspector-address.js @@ -0,0 +1,44 @@ +'use strict'; +const { PORT, mustCall, skipIfInspectorDisabled } = require('../common'); + +skipIfInspectorDisabled(); + +const assert = require('assert'); +const { spawn } = require('child_process'); + +function test(arg, expected, done) { + const args = [arg, '-p', 'process.debugPort']; + const proc = spawn(process.execPath, args); + proc.stdout.setEncoding('utf8'); + proc.stderr.setEncoding('utf8'); + let stdout = ''; + let stderr = ''; + proc.stdout.on('data', (data) => stdout += data); + proc.stderr.on('data', (data) => stderr += data); + proc.stdout.on('close', (hadErr) => assert(!hadErr)); + proc.stderr.on('close', (hadErr) => assert(!hadErr)); + proc.stderr.on('data', () => { + if (!stderr.includes('\n')) return; + assert(/Debugger listening on (.+)\./.test(stderr)); + assert.strictEqual(RegExp.$1, expected); + }); + proc.on('exit', (exitCode, signalCode) => { + assert.strictEqual(exitCode, 0); + assert.strictEqual(signalCode, null); + done(); + }); +} + +function one() { + test(`--inspect=${PORT}`, `127.0.0.1:${PORT}`, mustCall(two)); +} + +function two() { + test(`--inspect=0.0.0.0:${PORT}`, `0.0.0.0:${PORT}`, mustCall(three)); +} + +function three() { + test(`--inspect=127.0.0.1:${PORT}`, `127.0.0.1:${PORT}`, mustCall()); +} + +one();