1 'use strict'; 2 3 let hook; 4 let config; 5 6 const { 7 SafeSet, 8 } = primordials; 9 10 function lazyHookCreation() { 11 const inspector = internalBinding('inspector'); 12 const { createHook } = require('async_hooks'); 13 config = internalBinding('config'); 14 15 hook = createHook({ 16 init(asyncId, type, triggerAsyncId, resource) { 17 // It's difficult to tell which tasks will be recurring and which won't, 18 // therefore we mark all tasks as recurring. Based on the discussion 19 // in https://github.com/nodejs/node/pull/13870#discussion_r124515293, 20 // this should be fine as long as we call asyncTaskCanceled() too. 21 const recurring = true; 22 if (type === 'PROMISE') 23 this.promiseIds.add(asyncId); 24 else 25 inspector.asyncTaskScheduled(type, asyncId, recurring); 26 }, 27 28 before(asyncId) { 29 if (this.promiseIds.has(asyncId)) 30 return; 31 inspector.asyncTaskStarted(asyncId); 32 }, 33 34 after(asyncId) { 35 if (this.promiseIds.has(asyncId)) 36 return; 37 inspector.asyncTaskFinished(asyncId); 38 }, 39 40 destroy(asyncId) { 41 if (this.promiseIds.has(asyncId)) 42 return this.promiseIds.delete(asyncId); 43 inspector.asyncTaskCanceled(asyncId); 44 }, 45 }); 46 47 hook.promiseIds = new SafeSet(); 48 } 49 50 function enable() { 51 if (hook === undefined) lazyHookCreation(); 52 if (config.bits < 64) { 53 // V8 Inspector stores task ids as (void*) pointers. 54 // async_hooks store ids as 64bit numbers. 55 // As a result, we cannot reliably translate async_hook ids to V8 async_task 56 // ids on 32bit platforms. 57 process.emitWarning( 58 'Warning: Async stack traces in debugger are not available ' + 59 `on ${config.bits}bit platforms. The feature is disabled.`, 60 { 61 code: 'INSPECTOR_ASYNC_STACK_TRACES_NOT_AVAILABLE', 62 }); 63 } else { 64 hook.enable(); 65 } 66 } 67 68 function disable() { 69 if (hook === undefined) lazyHookCreation(); 70 hook.disable(); 71 } 72 73 module.exports = { 74 enable, 75 disable 76 }; 77