1// Flags: --expose-internals 2'use strict'; 3 4const common = require('../common'); 5const assert = require('assert'); 6const internal_async_hooks = require('internal/async_hooks'); 7const { spawn } = require('child_process'); 8const corruptedMsg = /async hook stack has become corrupted/; 9const heartbeatMsg = /heartbeat: still alive/; 10 11const { 12 newAsyncId, getDefaultTriggerAsyncId, 13 emitInit, emitBefore, emitAfter, emitDestroy 14} = internal_async_hooks; 15 16const initHooks = require('./init-hooks'); 17 18if (process.argv[2] === 'child') { 19 const hooks = initHooks(); 20 hooks.enable(); 21 22 // Once 'destroy' has been emitted, we can no longer emit 'before' 23 24 // Emitting 'before', 'after' and then 'destroy' 25 { 26 const asyncId = newAsyncId(); 27 const triggerId = getDefaultTriggerAsyncId(); 28 emitInit(asyncId, 'event1', triggerId, {}); 29 emitBefore(asyncId, triggerId); 30 emitAfter(asyncId); 31 emitDestroy(asyncId); 32 } 33 34 // Emitting 'before' after 'destroy' 35 { 36 const asyncId = newAsyncId(); 37 const triggerId = getDefaultTriggerAsyncId(); 38 emitInit(asyncId, 'event2', triggerId, {}); 39 emitDestroy(asyncId); 40 41 console.log('heartbeat: still alive'); 42 emitBefore(asyncId, triggerId); 43 } 44} else { 45 const args = ['--expose-internals'] 46 .concat(process.argv.slice(1)) 47 .concat('child'); 48 let errData = Buffer.from(''); 49 let outData = Buffer.from(''); 50 51 const child = spawn(process.execPath, args); 52 child.stderr.on('data', (d) => { errData = Buffer.concat([ errData, d ]); }); 53 child.stdout.on('data', (d) => { outData = Buffer.concat([ outData, d ]); }); 54 55 child.on('close', common.mustCall((code) => { 56 assert.strictEqual(code, 1); 57 assert.ok(heartbeatMsg.test(outData.toString()), 58 'did not crash until we reached offending line of code ' + 59 `(found ${outData})`); 60 assert.ok(corruptedMsg.test(errData.toString()), 61 'printed error contains corrupted message ' + 62 `(found ${errData})`); 63 })); 64} 65