2019-03-08 16:42:21 +01:00
|
|
|
// Flags: --expose-internals
|
2016-11-22 13:13:44 -03:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const common = require('../common');
|
|
|
|
const assert = require('assert');
|
2019-03-08 16:42:21 +01:00
|
|
|
const internal_async_hooks = require('internal/async_hooks');
|
2016-11-22 13:13:44 -03:00
|
|
|
const { spawn } = require('child_process');
|
|
|
|
const corruptedMsg = /async hook stack has become corrupted/;
|
|
|
|
const heartbeatMsg = /heartbeat: still alive/;
|
|
|
|
|
2019-03-08 16:42:21 +01:00
|
|
|
const {
|
|
|
|
newAsyncId, getDefaultTriggerAsyncId,
|
2022-11-21 12:43:47 -05:00
|
|
|
emitInit, emitBefore, emitAfter,
|
2019-03-08 16:42:21 +01:00
|
|
|
} = internal_async_hooks;
|
|
|
|
|
2016-11-22 13:13:44 -03:00
|
|
|
const initHooks = require('./init-hooks');
|
|
|
|
|
|
|
|
if (process.argv[2] === 'child') {
|
|
|
|
const hooks = initHooks();
|
|
|
|
hooks.enable();
|
|
|
|
|
2018-12-03 17:15:45 +01:00
|
|
|
// Async hooks enforce proper order of 'before' and 'after' invocations
|
2016-11-22 13:13:44 -03:00
|
|
|
|
|
|
|
// Proper ordering
|
2019-03-08 16:42:21 +01:00
|
|
|
{
|
|
|
|
const asyncId = newAsyncId();
|
|
|
|
const triggerId = getDefaultTriggerAsyncId();
|
|
|
|
emitInit(asyncId, 'event1', triggerId, {});
|
|
|
|
emitBefore(asyncId, triggerId);
|
|
|
|
emitAfter(asyncId);
|
|
|
|
}
|
2016-11-22 13:13:44 -03:00
|
|
|
|
|
|
|
// Improper ordering
|
|
|
|
// Emitting 'after' without 'before' which is illegal
|
2019-03-08 16:42:21 +01:00
|
|
|
{
|
|
|
|
const asyncId = newAsyncId();
|
|
|
|
const triggerId = getDefaultTriggerAsyncId();
|
|
|
|
emitInit(asyncId, 'event2', triggerId, {});
|
|
|
|
|
|
|
|
console.log('heartbeat: still alive');
|
|
|
|
emitAfter(asyncId);
|
|
|
|
}
|
2016-11-22 13:13:44 -03:00
|
|
|
} else {
|
2019-03-08 16:42:21 +01:00
|
|
|
const args = ['--expose-internals']
|
|
|
|
.concat(process.argv.slice(1))
|
|
|
|
.concat('child');
|
2016-11-22 13:13:44 -03:00
|
|
|
let errData = Buffer.from('');
|
|
|
|
let outData = Buffer.from('');
|
|
|
|
|
|
|
|
const child = spawn(process.execPath, args);
|
|
|
|
child.stderr.on('data', (d) => { errData = Buffer.concat([ errData, d ]); });
|
|
|
|
child.stdout.on('data', (d) => { outData = Buffer.concat([ outData, d ]); });
|
|
|
|
|
2025-06-03 14:07:24 +03:00
|
|
|
child.on('close', common.mustCall((code, signal) => {
|
|
|
|
if ((common.isAIX ||
|
|
|
|
(common.isLinux && process.arch === 'x64')) &&
|
|
|
|
signal === 'SIGABRT') {
|
|
|
|
// XXX: The child process could be aborted due to unknown reasons. Work around it.
|
|
|
|
} else {
|
|
|
|
assert.strictEqual(signal, null);
|
|
|
|
assert.strictEqual(code, 1);
|
|
|
|
}
|
2021-08-29 10:14:22 +02:00
|
|
|
assert.match(outData.toString(), heartbeatMsg,
|
|
|
|
'did not crash until we reached offending line of code ' +
|
|
|
|
`(found ${outData})`);
|
|
|
|
assert.match(errData.toString(), corruptedMsg,
|
|
|
|
'printed error contains corrupted message ' +
|
|
|
|
`(found ${errData})`);
|
2016-11-22 13:13:44 -03:00
|
|
|
}));
|
|
|
|
}
|