mirror of https://github.com/lukechilds/node.git
Browse Source
Wait for a sought-for symbol to appear instead of just hard-killing subprocesses at 2s timeout. Fix: #4427 PR-URL: https://github.com/nodejs/node/pull/8542 Reviewed-By: Rich Trott <rtrott@gmail.com>v6.x
committed by
Jeremiah Senkpiel
6 changed files with 155 additions and 67 deletions
@ -0,0 +1,56 @@ |
|||
'use strict'; |
|||
const common = require('../common'); |
|||
const fs = require('fs'); |
|||
const cp = require('child_process'); |
|||
const path = require('path'); |
|||
|
|||
common.refreshTmpDir(); |
|||
|
|||
const LOG_FILE = path.join(common.tmpDir, 'tick-processor.log'); |
|||
const RETRY_TIMEOUT = 750; |
|||
|
|||
function runTest(test) { |
|||
const proc = cp.spawn(process.execPath, [ |
|||
'--no_logfile_per_isolate', |
|||
'--logfile=-', |
|||
'--prof', |
|||
'-pe', test.code |
|||
], { |
|||
stdio: [ null, 'pipe', 'inherit' ] |
|||
}); |
|||
|
|||
let ticks = ''; |
|||
proc.stdout.on('data', chunk => ticks += chunk); |
|||
|
|||
// Try to match after timeout
|
|||
setTimeout(() => { |
|||
match(test.pattern, proc, () => ticks); |
|||
}, RETRY_TIMEOUT); |
|||
} |
|||
|
|||
function match(pattern, parent, ticks) { |
|||
// Store current ticks log
|
|||
fs.writeFileSync(LOG_FILE, ticks()); |
|||
|
|||
const proc = cp.spawn(process.execPath, [ |
|||
'--prof-process', |
|||
'--call-graph-size=10', |
|||
LOG_FILE |
|||
], { |
|||
stdio: [ null, 'pipe', 'inherit' ] |
|||
}); |
|||
|
|||
let out = ''; |
|||
proc.stdout.on('data', chunk => out += chunk); |
|||
proc.stdout.on('end', () => { |
|||
// Retry after timeout
|
|||
if (!pattern.test(out)) |
|||
return setTimeout(() => match(pattern, parent, ticks), RETRY_TIMEOUT); |
|||
|
|||
parent.kill('SIGTERM'); |
|||
|
|||
fs.unlinkSync(LOG_FILE); |
|||
}); |
|||
} |
|||
|
|||
exports.runTest = runTest; |
@ -0,0 +1,33 @@ |
|||
'use strict'; |
|||
const common = require('../common'); |
|||
const path = require('path'); |
|||
|
|||
// TODO(mhdawson) Currently the test-tick-processor functionality in V8
|
|||
// depends on addresses being smaller than a full 64 bits. Aix supports
|
|||
// the full 64 bits and the result is that it does not process the
|
|||
// addresses correctly and runs out of memory
|
|||
// Disabling until we get a fix upstreamed into V8
|
|||
if (common.isAix) { |
|||
common.skip('Aix address range too big for scripts.'); |
|||
return; |
|||
} |
|||
|
|||
const base = require(path.join(common.fixturesDir, 'tick-processor-base.js')); |
|||
|
|||
if (common.isWindows || |
|||
common.isSunOS || |
|||
common.isAix || |
|||
common.isLinuxPPCBE || |
|||
common.isFreeBSD) { |
|||
common.skip('C++ symbols are not mapped for this os.'); |
|||
return; |
|||
} |
|||
|
|||
base.runTest({ |
|||
pattern: /Builtin_DateNow/, |
|||
code: `function f() {
|
|||
this.ts = Date.now(); |
|||
setImmediate(function() { new f(); }); |
|||
}; |
|||
f();` |
|||
}); |
@ -0,0 +1,33 @@ |
|||
'use strict'; |
|||
const common = require('../common'); |
|||
const path = require('path'); |
|||
|
|||
// TODO(mhdawson) Currently the test-tick-processor functionality in V8
|
|||
// depends on addresses being smaller than a full 64 bits. Aix supports
|
|||
// the full 64 bits and the result is that it does not process the
|
|||
// addresses correctly and runs out of memory
|
|||
// Disabling until we get a fix upstreamed into V8
|
|||
if (common.isAix) { |
|||
common.skip('Aix address range too big for scripts.'); |
|||
return; |
|||
} |
|||
|
|||
const base = require(path.join(common.fixturesDir, 'tick-processor-base.js')); |
|||
|
|||
if (common.isWindows || |
|||
common.isSunOS || |
|||
common.isAix || |
|||
common.isLinuxPPCBE || |
|||
common.isFreeBSD) { |
|||
common.skip('C++ symbols are not mapped for this os.'); |
|||
return; |
|||
} |
|||
|
|||
base.runTest({ |
|||
pattern: /RunInDebugContext/, |
|||
code: `function f() {
|
|||
require(\'vm\').runInDebugContext(\'Debug\'); |
|||
setImmediate(function() { f(); }); |
|||
}; |
|||
f();` |
|||
}); |
@ -0,0 +1,28 @@ |
|||
'use strict'; |
|||
const common = require('../common'); |
|||
const path = require('path'); |
|||
|
|||
// TODO(mhdawson) Currently the test-tick-processor functionality in V8
|
|||
// depends on addresses being smaller than a full 64 bits. Aix supports
|
|||
// the full 64 bits and the result is that it does not process the
|
|||
// addresses correctly and runs out of memory
|
|||
// Disabling until we get a fix upstreamed into V8
|
|||
if (common.isAix) { |
|||
common.skip('Aix address range too big for scripts.'); |
|||
return; |
|||
} |
|||
|
|||
const base = require(path.join(common.fixturesDir, 'tick-processor-base.js')); |
|||
|
|||
// Unknown checked for to prevent flakiness, if pattern is not found,
|
|||
// then a large number of unknown ticks should be present
|
|||
base.runTest({ |
|||
pattern: /LazyCompile.*\[eval\]:1|.*% UNKNOWN/, |
|||
code: `function f() {
|
|||
for (var i = 0; i < 1000000; i++) { |
|||
i++; |
|||
} |
|||
setImmediate(function() { f(); }); |
|||
}; |
|||
f();` |
|||
}); |
@ -1,66 +0,0 @@ |
|||
'use strict'; |
|||
const common = require('../common'); |
|||
const fs = require('fs'); |
|||
const assert = require('assert'); |
|||
const cp = require('child_process'); |
|||
|
|||
// TODO(mhdawson) Currently the test-tick-processor functionality in V8
|
|||
// depends on addresses being smaller than a full 64 bits. Aix supports
|
|||
// the full 64 bits and the result is that it does not process the
|
|||
// addresses correctly and runs out of memory
|
|||
// Disabling until we get a fix upstreamed into V8
|
|||
if (common.isAix) { |
|||
common.skip('Aix address range too big for scripts.'); |
|||
return; |
|||
} |
|||
|
|||
common.refreshTmpDir(); |
|||
process.chdir(common.tmpDir); |
|||
// Unknown checked for to prevent flakiness, if pattern is not found,
|
|||
// then a large number of unknown ticks should be present
|
|||
runTest(/LazyCompile.*\[eval\]:1|.*% UNKNOWN/, |
|||
`function f() {
|
|||
for (var i = 0; i < 1000000; i++) { |
|||
i++; |
|||
} |
|||
setImmediate(function() { f(); }); |
|||
}; |
|||
setTimeout(function() { process.exit(0); }, 2000); |
|||
f();`);
|
|||
if (common.isWindows || |
|||
common.isSunOS || |
|||
common.isAix || |
|||
common.isLinuxPPCBE || |
|||
common.isFreeBSD) { |
|||
common.skip('C++ symbols are not mapped for this os.'); |
|||
return; |
|||
} |
|||
runTest(/RunInDebugContext/, |
|||
`function f() {
|
|||
require(\'vm\').runInDebugContext(\'Debug\'); |
|||
setImmediate(function() { f(); }); |
|||
}; |
|||
setTimeout(function() { process.exit(0); }, 2000); |
|||
f();`);
|
|||
|
|||
runTest(/Builtin_DateNow/, |
|||
`function f() {
|
|||
this.ts = Date.now(); |
|||
setImmediate(function() { new f(); }); |
|||
}; |
|||
setTimeout(function() { process.exit(0); }, 2000); |
|||
f();`);
|
|||
|
|||
function runTest(pattern, code) { |
|||
cp.execFileSync(process.execPath, ['-prof', '-pe', code]); |
|||
var matches = fs.readdirSync(common.tmpDir); |
|||
|
|||
assert.strictEqual(matches.length, 1, 'There should be a single log file.'); |
|||
|
|||
var log = matches[0]; |
|||
var out = cp.execSync(process.execPath + |
|||
' --prof-process --call-graph-size=10 ' + log, |
|||
{encoding: 'utf8'}); |
|||
assert(pattern.test(out), `${pattern} not matching ${out}`); |
|||
fs.unlinkSync(log); |
|||
} |
Loading…
Reference in new issue