deps: update node-inspect to 1.11.3

Highlights:

* Using a random port works (`node inspect --port=0 script.js`)
* `takeHeapSnapshot()` creates valid snapshots again

PR-URL: https://github.com/nodejs/node/pull/18354
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
This commit is contained in:
Jan Krems 2018-01-24 10:42:54 -08:00 committed by Ruben Bridgewater
parent 7ff4888ed2
commit 02b3bbc5e2
No known key found for this signature in database
GPG Key ID: F07496B3EB3C1762
10 changed files with 118 additions and 40 deletions

View File

@ -1,3 +1,12 @@
### 1.11.3
* [`93caa0f`](https://github.com/nodejs/node-inspect/commit/93caa0f5267c7ab452b258d3b03329a0bb5ac7f7) **docs:** Add missing oc in protocol
* [`2d87cbe`](https://github.com/nodejs/node-inspect/commit/2d87cbe76aa968dfc1ac69d9571af1be81abd8e0) **fix:** Make --inspect-port=0 work
* [`ebfd02e`](https://github.com/nodejs/node-inspect/commit/ebfd02ece9b642586023f7791da71defeb13d746) **chore:** Bump tap to 10.7
* [`c07adb1`](https://github.com/nodejs/node-inspect/commit/c07adb17b164c1cf3da8d38659ea9f5d7ff42e9c) **test:** Use useful break location
* [`94f0bf9`](https://github.com/nodejs/node-inspect/commit/94f0bf97d24c376baf3ecced2088d81715a73464) **fix:** Fix `takeHeapSnapshot()` truncation bug
### 1.11.2 ### 1.11.2
* [`42e0cd1`](https://github.com/nodejs/node-inspect/commit/42e0cd111d89ed09faba1c0ec45089b0b44de011) **fix:** look for generic hint text * [`42e0cd1`](https://github.com/nodejs/node-inspect/commit/42e0cd111d89ed09faba1c0ec45089b0b44de011) **fix:** look for generic hint text

View File

@ -10,7 +10,7 @@ node has two options:
1. `node --debug <file>`: Start `file` with remote debugging enabled. 1. `node --debug <file>`: Start `file` with remote debugging enabled.
2. `node debug <file>`: Start an interactive CLI debugger for `<file>`. 2. `node debug <file>`: Start an interactive CLI debugger for `<file>`.
But for the Chrome inspector protol, But for the Chrome inspector protocol,
there's only one: `node --inspect <file>`. there's only one: `node --inspect <file>`.
This project tries to provide the missing second option This project tries to provide the missing second option

View File

@ -42,18 +42,9 @@ const [ InspectClient, createRepl ] =
const debuglog = util.debuglog('inspect'); const debuglog = util.debuglog('inspect');
const DEBUG_PORT_PATTERN = /^--(?:debug|inspect)(?:-port|-brk)?=(\d{1,5})$/;
function getDefaultPort() {
for (const arg of process.execArgv) {
const match = arg.match(DEBUG_PORT_PATTERN);
if (match) {
return +match[1];
}
}
return 9229;
}
function portIsFree(host, port, timeout = 2000) { function portIsFree(host, port, timeout = 2000) {
if (port === 0) return Promise.resolve(); // Binding to a random port.
const retryDelay = 150; const retryDelay = 150;
let didTimeOut = false; let didTimeOut = false;
@ -110,9 +101,11 @@ function runScript(script, scriptArgs, inspectHost, inspectPort, childPrint) {
let output = ''; let output = '';
function waitForListenHint(text) { function waitForListenHint(text) {
output += text; output += text;
if (/Debugger listening on/.test(output)) { if (/Debugger listening on ws:\/\/\[?(.+?)\]?:(\d+)\//.test(output)) {
const host = RegExp.$1;
const port = Number.parseInt(RegExp.$2);
child.stderr.removeListener('data', waitForListenHint); child.stderr.removeListener('data', waitForListenHint);
resolve(child); resolve([child, port, host]);
} }
} }
@ -160,10 +153,11 @@ class NodeInspector {
options.port, options.port,
this.childPrint.bind(this)); this.childPrint.bind(this));
} else { } else {
this._runScript = () => Promise.resolve(null); this._runScript =
() => Promise.resolve([null, options.port, options.host]);
} }
this.client = new InspectClient(options.port, options.host); this.client = new InspectClient();
this.domainNames = ['Debugger', 'HeapProfiler', 'Profiler', 'Runtime']; this.domainNames = ['Debugger', 'HeapProfiler', 'Profiler', 'Runtime'];
this.domainNames.forEach((domain) => { this.domainNames.forEach((domain) => {
@ -223,9 +217,8 @@ class NodeInspector {
run() { run() {
this.killChild(); this.killChild();
const { host, port } = this.options;
return this._runScript().then((child) => { return this._runScript().then(([child, port, host]) => {
this.child = child; this.child = child;
let connectionAttempts = 0; let connectionAttempts = 0;
@ -233,7 +226,7 @@ class NodeInspector {
++connectionAttempts; ++connectionAttempts;
debuglog('connection attempt #%d', connectionAttempts); debuglog('connection attempt #%d', connectionAttempts);
this.stdout.write('.'); this.stdout.write('.');
return this.client.connect() return this.client.connect(port, host)
.then(() => { .then(() => {
debuglog('connection established'); debuglog('connection established');
this.stdout.write(' ok'); this.stdout.write(' ok');
@ -288,7 +281,7 @@ class NodeInspector {
function parseArgv([target, ...args]) { function parseArgv([target, ...args]) {
let host = '127.0.0.1'; let host = '127.0.0.1';
let port = getDefaultPort(); let port = 9229;
let isRemote = false; let isRemote = false;
let script = target; let script = target;
let scriptArgs = args; let scriptArgs = args;

View File

@ -164,12 +164,12 @@ function decodeFrameHybi17(data) {
} }
class Client extends EventEmitter { class Client extends EventEmitter {
constructor(port, host) { constructor() {
super(); super();
this.handleChunk = this._handleChunk.bind(this); this.handleChunk = this._handleChunk.bind(this);
this._port = port; this._port = undefined;
this._host = host; this._host = undefined;
this.reset(); this.reset();
} }
@ -284,7 +284,9 @@ class Client extends EventEmitter {
}); });
} }
connect() { connect(port, host) {
this._port = port;
this._host = host;
return this._discoverWebsocketPath() return this._discoverWebsocketPath()
.then((urlPath) => this._connectWebsocket(urlPath)); .then((urlPath) => this._connectWebsocket(urlPath));
} }

View File

@ -900,10 +900,8 @@ function createRepl(inspector) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const absoluteFile = Path.resolve(filename); const absoluteFile = Path.resolve(filename);
const writer = FS.createWriteStream(absoluteFile); const writer = FS.createWriteStream(absoluteFile);
let totalSize;
let sizeWritten = 0; let sizeWritten = 0;
function onProgress({ done, total, finished }) { function onProgress({ done, total, finished }) {
totalSize = total;
if (finished) { if (finished) {
print('Heap snaphost prepared.'); print('Heap snaphost prepared.');
} else { } else {
@ -913,13 +911,18 @@ function createRepl(inspector) {
function onChunk({ chunk }) { function onChunk({ chunk }) {
sizeWritten += chunk.length; sizeWritten += chunk.length;
writer.write(chunk); writer.write(chunk);
print(`Writing snapshot: ${sizeWritten}/${totalSize}`, true); print(`Writing snapshot: ${sizeWritten}`, true);
if (sizeWritten >= totalSize) { }
writer.end(); function onResolve() {
writer.end(() => {
teardown(); teardown();
print(`Wrote snapshot: ${absoluteFile}`); print(`Wrote snapshot: ${absoluteFile}`);
resolve(); resolve();
} });
}
function onReject(error) {
teardown();
reject(error);
} }
function teardown() { function teardown() {
HeapProfiler.removeListener( HeapProfiler.removeListener(
@ -932,10 +935,7 @@ function createRepl(inspector) {
print('Heap snapshot: 0/0', true); print('Heap snapshot: 0/0', true);
HeapProfiler.takeHeapSnapshot({ reportProgress: true }) HeapProfiler.takeHeapSnapshot({ reportProgress: true })
.then(null, (error) => { .then(onResolve, onReject);
teardown();
reject(error);
});
}); });
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "node-inspect", "name": "node-inspect",
"version": "1.11.2", "version": "1.11.3",
"description": "Node Inspect", "description": "Node Inspect",
"license": "MIT", "license": "MIT",
"main": "lib/_inspect.js", "main": "lib/_inspect.js",
@ -29,7 +29,7 @@
"devDependencies": { "devDependencies": {
"eslint": "^3.10.2", "eslint": "^3.10.2",
"nlm": "^3.0.0", "nlm": "^3.0.0",
"tap": "^7.1.2" "tap": "^10.7.0"
}, },
"author": { "author": {
"name": "Jan Krems", "name": "Jan Krems",

View File

@ -134,7 +134,7 @@ test('sb before loading file', (t) => {
return cli.waitForInitialBreak() return cli.waitForInitialBreak()
.then(() => cli.waitForPrompt()) .then(() => cli.waitForPrompt())
.then(() => cli.command('sb("other.js", 3)')) .then(() => cli.command('sb("other.js", 2)'))
.then(() => { .then(() => {
t.match( t.match(
cli.output, cli.output,
@ -145,7 +145,7 @@ test('sb before loading file', (t) => {
.then(() => { .then(() => {
t.match( t.match(
cli.output, cli.output,
`break in ${otherScript}:3`, `break in ${otherScript}:2`,
'found breakpoint in file that was not loaded yet'); 'found breakpoint in file that was not loaded yet');
}) })
.then(() => cli.quit()) .then(() => cli.quit())

View File

@ -0,0 +1,34 @@
'use strict';
const { test } = require('tap');
const { readFileSync, unlinkSync } = require('fs');
const startCLI = require('./start-cli');
const filename = 'node.heapsnapshot';
function cleanup() {
try {
unlinkSync(filename);
} catch (_) {
// Ignore.
}
}
cleanup();
test('Heap profiler take snapshot', (t) => {
const cli = startCLI(['examples/empty.js']);
function onFatal(error) {
cli.quit();
throw error;
}
// Check that the snapshot is valid JSON.
return cli.waitForInitialBreak()
.then(() => cli.waitForPrompt())
.then(() => cli.command('takeHeapSnapshot()'))
.then(() => JSON.parse(readFileSync(filename, 'utf8')))
.then(() => cleanup())
.then(() => cli.quit())
.then(null, onFatal);
});

View File

@ -26,6 +26,46 @@ test('custom port', (t) => {
}); });
}); });
test('random port', (t) => {
const script = Path.join('examples', 'three-lines.js');
const cli = startCLI(['--port=0', script]);
return cli.waitForInitialBreak()
.then(() => cli.waitForPrompt())
.then(() => {
t.match(cli.output, 'debug>', 'prints a prompt');
t.match(
cli.output,
/< Debugger listening on /,
'forwards child output');
})
.then(() => cli.quit())
.then((code) => {
t.equal(code, 0, 'exits with success');
});
});
test('random port with --inspect-port=0', (t) => {
const script = Path.join('examples', 'three-lines.js');
const cli = startCLI([script], ['--inspect-port=0']);
return cli.waitForInitialBreak()
.then(() => cli.waitForPrompt())
.then(() => {
t.match(cli.output, 'debug>', 'prints a prompt');
t.match(
cli.output,
/< Debugger listening on /,
'forwards child output');
})
.then(() => cli.quit())
.then((code) => {
t.equal(code, 0, 'exits with success');
});
});
test('examples/three-lines.js', (t) => { test('examples/three-lines.js', (t) => {
const script = Path.join('examples', 'three-lines.js'); const script = Path.join('examples', 'three-lines.js');
const cli = startCLI([script]); const cli = startCLI([script]);

View File

@ -16,8 +16,8 @@ const BREAK_MESSAGE = new RegExp('(?:' + [
'exception', 'other', 'promiseRejection', 'exception', 'other', 'promiseRejection',
].join('|') + ') in', 'i'); ].join('|') + ') in', 'i');
function startCLI(args) { function startCLI(args, flags = []) {
const child = spawn(process.execPath, [CLI, ...args]); const child = spawn(process.execPath, [...flags, CLI, ...args]);
let isFirstStdoutChunk = true; let isFirstStdoutChunk = true;
const outputBuffer = []; const outputBuffer = [];