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