tools, test: fix prof polyfill readline
`node --prof foo.js` may not print the full profile log file, leaving the last line broken (for example `tick,`. When that happens, `readline` will be stuck in an infinite loop. This patch fixes it. Also introduced `common.isCPPSymbolsNotMapped` to avoid duplicated code on tick-processor tests. PR-URL: https://github.com/nodejs/node/pull/18641 Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Matheus Marchini <matheus@sthima.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
parent
513d939720
commit
38f04d4da1
@ -96,6 +96,13 @@ function readline() {
|
|||||||
if (line.length === 0) {
|
if (line.length === 0) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
if (bytes === 0) {
|
||||||
|
process.emitWarning(`Profile file ${logFile} is broken`, {
|
||||||
|
code: 'BROKEN_PROFILE_FILE',
|
||||||
|
detail: `${JSON.stringify(line)} at the file end is broken`
|
||||||
|
});
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,6 +243,11 @@ Platform check for Windows.
|
|||||||
|
|
||||||
Platform check for Windows 32-bit on Windows 64-bit.
|
Platform check for Windows 32-bit on Windows 64-bit.
|
||||||
|
|
||||||
|
### isCPPSymbolsNotMapped
|
||||||
|
* [<Boolean>]
|
||||||
|
|
||||||
|
Platform check for C++ symbols are mapped or not.
|
||||||
|
|
||||||
### leakedGlobals()
|
### leakedGlobals()
|
||||||
* return [<Array>]
|
* return [<Array>]
|
||||||
|
|
||||||
|
@ -803,3 +803,8 @@ exports.hijackStdout = hijackStdWritable.bind(null, 'stdout');
|
|||||||
exports.hijackStderr = hijackStdWritable.bind(null, 'stderr');
|
exports.hijackStderr = hijackStdWritable.bind(null, 'stderr');
|
||||||
exports.restoreStdout = restoreWritable.bind(null, 'stdout');
|
exports.restoreStdout = restoreWritable.bind(null, 'stdout');
|
||||||
exports.restoreStderr = restoreWritable.bind(null, 'stderr');
|
exports.restoreStderr = restoreWritable.bind(null, 'stderr');
|
||||||
|
exports.isCPPSymbolsNotMapped = exports.isWindows ||
|
||||||
|
exports.isSunOS ||
|
||||||
|
exports.isAIX ||
|
||||||
|
exports.isLinuxPPCBE ||
|
||||||
|
exports.isFreeBSD;
|
||||||
|
@ -4,12 +4,9 @@ const common = require('../common');
|
|||||||
if (!common.enoughTestCpu)
|
if (!common.enoughTestCpu)
|
||||||
common.skip('test is CPU-intensive');
|
common.skip('test is CPU-intensive');
|
||||||
|
|
||||||
if (common.isWindows ||
|
if (common.isCPPSymbolsNotMapped) {
|
||||||
common.isSunOS ||
|
|
||||||
common.isAIX ||
|
|
||||||
common.isLinuxPPCBE ||
|
|
||||||
common.isFreeBSD)
|
|
||||||
common.skip('C++ symbols are not mapped for this os.');
|
common.skip('C++ symbols are not mapped for this os.');
|
||||||
|
}
|
||||||
|
|
||||||
const base = require('./tick-processor-base.js');
|
const base = require('./tick-processor-base.js');
|
||||||
|
|
||||||
|
@ -4,12 +4,9 @@ const common = require('../common');
|
|||||||
if (!common.enoughTestCpu)
|
if (!common.enoughTestCpu)
|
||||||
common.skip('test is CPU-intensive');
|
common.skip('test is CPU-intensive');
|
||||||
|
|
||||||
if (common.isWindows ||
|
if (common.isCPPSymbolsNotMapped) {
|
||||||
common.isSunOS ||
|
|
||||||
common.isAIX ||
|
|
||||||
common.isLinuxPPCBE ||
|
|
||||||
common.isFreeBSD)
|
|
||||||
common.skip('C++ symbols are not mapped for this os.');
|
common.skip('C++ symbols are not mapped for this os.');
|
||||||
|
}
|
||||||
|
|
||||||
const base = require('./tick-processor-base.js');
|
const base = require('./tick-processor-base.js');
|
||||||
|
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
'use strict';
|
||||||
|
const common = require('../common');
|
||||||
|
const tmpdir = require('../common/tmpdir');
|
||||||
|
tmpdir.refresh();
|
||||||
|
|
||||||
|
if (!common.enoughTestCpu)
|
||||||
|
common.skip('test is CPU-intensive');
|
||||||
|
|
||||||
|
if (common.isCPPSymbolsNotMapped) {
|
||||||
|
common.skip('C++ symbols are not mapped for this OS.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test will produce a broken profile log.
|
||||||
|
// ensure prof-polyfill not stuck in infinite loop
|
||||||
|
// and success process
|
||||||
|
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
const cp = require('child_process');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const LOG_FILE = path.join(tmpdir.path, 'tick-processor.log');
|
||||||
|
const RETRY_TIMEOUT = 150;
|
||||||
|
const BROKEN_PART = 'tick,';
|
||||||
|
const WARN_REG_EXP = /\(node:\d+\) \[BROKEN_PROFILE_FILE] Warning: Profile file .* is broken/;
|
||||||
|
const WARN_DETAIL_REG_EXP = /".*tick," at the file end is broken/;
|
||||||
|
|
||||||
|
const code = `function f() {
|
||||||
|
this.ts = Date.now();
|
||||||
|
setImmediate(function() { new f(); });
|
||||||
|
};
|
||||||
|
f();`;
|
||||||
|
|
||||||
|
const proc = cp.spawn(process.execPath, [
|
||||||
|
'--no_logfile_per_isolate',
|
||||||
|
'--logfile=-',
|
||||||
|
'--prof',
|
||||||
|
'-pe', code
|
||||||
|
], {
|
||||||
|
stdio: ['ignore', 'pipe', 'inherit']
|
||||||
|
});
|
||||||
|
|
||||||
|
let ticks = '';
|
||||||
|
proc.stdout.on('data', (chunk) => ticks += chunk);
|
||||||
|
|
||||||
|
|
||||||
|
function runPolyfill(content) {
|
||||||
|
proc.kill();
|
||||||
|
content += BROKEN_PART;
|
||||||
|
fs.writeFileSync(LOG_FILE, content);
|
||||||
|
const child = cp.spawnSync(
|
||||||
|
`${process.execPath}`,
|
||||||
|
[
|
||||||
|
'--prof-process', LOG_FILE
|
||||||
|
]);
|
||||||
|
assert(WARN_REG_EXP.test(child.stderr.toString()));
|
||||||
|
assert(WARN_DETAIL_REG_EXP.test(child.stderr.toString()));
|
||||||
|
assert.strictEqual(child.status, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => runPolyfill(ticks), RETRY_TIMEOUT);
|
@ -4,12 +4,9 @@ const common = require('../common');
|
|||||||
if (!common.enoughTestCpu)
|
if (!common.enoughTestCpu)
|
||||||
common.skip('test is CPU-intensive');
|
common.skip('test is CPU-intensive');
|
||||||
|
|
||||||
if (common.isWindows ||
|
if (common.isCPPSymbolsNotMapped) {
|
||||||
common.isSunOS ||
|
|
||||||
common.isAIX ||
|
|
||||||
common.isLinuxPPCBE ||
|
|
||||||
common.isFreeBSD)
|
|
||||||
common.skip('C++ symbols are not mapped for this os.');
|
common.skip('C++ symbols are not mapped for this os.');
|
||||||
|
}
|
||||||
|
|
||||||
const base = require('./tick-processor-base.js');
|
const base = require('./tick-processor-base.js');
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user