• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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