From 4e682b64cfaa94baceca3bfd5956d061575f4ed3 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Fri, 12 Dec 2025 13:02:25 +0100 Subject: [PATCH 1/7] async_hooks: add --enable-async-hooks flag Add a new `--enable-async-hooks` flag that must be passed to enable `async_hooks.createHook()`. This is a breaking change - createHook is now disabled by default. When createHook() is called without the flag, it throws ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED with a message indicating that the flag is required. This change affects all code using async_hooks.createHook(), including APM tools and debugging utilities. Users must now explicitly opt-in to this functionality. BREAKING CHANGE: async_hooks.createHook() now requires the `--enable-async-hooks` flag. Signed-off-by: Matteo Collina --- doc/api/cli.md | 41 ++++++++++ doc/api/errors.md | 13 +++ doc/node.1 | 32 ++++++++ lib/async_hooks.js | 5 ++ lib/internal/async_hooks.js | 79 +++++++++++++++++++ lib/internal/errors.js | 2 + lib/internal/inspector_async_hook.js | 2 +- src/node_options.cc | 4 + src/node_options.h | 1 + test/addons/async-resource/test.js | 1 + .../addons/callback-scope/test-async-hooks.js | 1 + test/async-hooks/init-hooks.js | 2 +- test/async-hooks/test-async-await.js | 1 + .../test-async-exec-resource-http-32060.js | 1 + .../test-async-exec-resource-http-agent.js | 1 + .../test-async-exec-resource-http.js | 1 + .../test-async-exec-resource-match.js | 1 + .../test-async-local-storage-gcable.js | 2 +- test/async-hooks/test-callback-error.js | 9 ++- test/async-hooks/test-crypto-pbkdf2.js | 1 + test/async-hooks/test-crypto-randomBytes.js | 1 + test/async-hooks/test-destroy-not-blocked.js | 2 +- test/async-hooks/test-disable-in-init.js | 1 + ...est-embedder.api.async-resource-no-type.js | 3 +- .../test-embedder.api.async-resource.js | 1 + .../test-emit-after-on-destroyed.js | 4 +- test/async-hooks/test-emit-before-after.js | 2 +- .../test-emit-before-on-destroyed.js | 4 +- test/async-hooks/test-emit-init.js | 2 +- test/async-hooks/test-enable-disable.js | 1 + test/async-hooks/test-enable-in-init.js | 1 + test/async-hooks/test-filehandle-no-reuse.js | 1 + test/async-hooks/test-fseventwrap.js | 1 + test/async-hooks/test-fsreqcallback-access.js | 1 + .../test-fsreqcallback-readFile.js | 1 + test/async-hooks/test-getaddrinforeqwrap.js | 1 + test/async-hooks/test-getnameinforeqwrap.js | 1 + test/async-hooks/test-graph.fsreq-readFile.js | 1 + test/async-hooks/test-graph.http.js | 1 + test/async-hooks/test-graph.intervals.js | 1 + test/async-hooks/test-graph.pipe.js | 1 + test/async-hooks/test-graph.pipeconnect.js | 1 + test/async-hooks/test-graph.shutdown.js | 1 + test/async-hooks/test-graph.signal.js | 1 + test/async-hooks/test-graph.statwatcher.js | 1 + test/async-hooks/test-graph.tcp.js | 1 + test/async-hooks/test-graph.timeouts.js | 1 + test/async-hooks/test-graph.tls-write-12.js | 1 + test/async-hooks/test-graph.tls-write.js | 1 + .../test-http-agent-handle-reuse-parallel.js | 2 +- .../test-http-agent-handle-reuse-serial.js | 2 +- test/async-hooks/test-httpparser-reuse.js | 1 + test/async-hooks/test-httpparser.request.js | 2 +- test/async-hooks/test-httpparser.response.js | 2 +- test/async-hooks/test-immediate.js | 1 + test/async-hooks/test-improper-order.js | 4 +- test/async-hooks/test-improper-unwind.js | 4 +- test/async-hooks/test-late-hook-enable.js | 1 + .../test-nexttick-default-trigger.js | 1 + test/async-hooks/test-pipeconnectwrap.js | 1 + test/async-hooks/test-pipewrap.js | 2 +- ...promise.chain-promise-before-init-hooks.js | 1 + test/async-hooks/test-promise.js | 1 + .../test-promise.promise-before-init-hooks.js | 1 + test/async-hooks/test-querywrap.js | 2 +- test/async-hooks/test-queue-microtask.js | 1 + test/async-hooks/test-shutdownwrap.js | 1 + test/async-hooks/test-signalwrap.js | 1 + test/async-hooks/test-statwatcher.js | 1 + test/async-hooks/test-tcpwrap.js | 1 + test/async-hooks/test-timers.setInterval.js | 1 + test/async-hooks/test-timers.setTimeout.js | 1 + test/async-hooks/test-tlswrap.js | 1 + .../test-track-promises-default.js | 1 + .../test-track-promises-false-check.js | 2 +- test/async-hooks/test-track-promises-false.js | 1 + test/async-hooks/test-track-promises-true.js | 1 + .../test-track-promises-validation.js | 1 + test/async-hooks/test-ttywrap.readstream.js | 1 + test/async-hooks/test-udpsendwrap.js | 2 +- test/async-hooks/test-udpwrap.js | 1 + .../test-unhandled-exception-valid-ids.js | 1 + .../test-unhandled-rejection-context.js | 1 + test/async-hooks/test-writewrap.js | 1 + .../test-zlib.zlib-binding.deflate.js | 2 +- .../test-vm-compile-function-leak.js | 2 +- .../test-vm-contextified-script-leak.js | 2 +- .../test-vm-source-text-module-leak.js | 2 +- .../test-vm-synthetic-module-leak.js | 2 +- test/node-api/test_async/test-async-hooks.js | 1 + .../test-gcable-callback.js | 2 +- test/node-api/test_async_context/test.js | 2 +- .../test_callback_scope/test-async-hooks.js | 1 + .../test_make_callback/test-async-hooks.js | 1 + test/parallel/test-async-hooks-async-await.js | 1 + ...t-async-hooks-asyncresource-constructor.js | 1 + .../test-async-hooks-close-during-destroy.js | 1 + test/parallel/test-async-hooks-constructor.js | 1 + ...ync-hooks-correctly-switch-promise-hook.js | 1 + ...nc-hooks-create-hook-disabled-internals.js | 38 +++++++++ .../test-async-hooks-create-hook-disabled.js | 15 ++++ .../test-async-hooks-create-hook-enabled.js | 18 +++++ .../test-async-hooks-destroy-on-gc.js | 2 +- ...test-async-hooks-disable-during-promise.js | 1 + .../test-async-hooks-disable-gc-tracking.js | 2 +- ...ync-hooks-enable-before-promise-resolve.js | 1 + .../test-async-hooks-enable-disable-enable.js | 1 + .../test-async-hooks-enable-disable.js | 1 + .../test-async-hooks-enable-during-promise.js | 1 + .../test-async-hooks-enable-recursive.js | 1 + .../test-async-hooks-enabledhooksexits.js | 2 +- ...nc-hooks-execution-async-resource-await.js | 1 + ...st-async-hooks-execution-async-resource.js | 1 + test/parallel/test-async-hooks-fatal-error.js | 3 +- .../test-async-hooks-http-agent-destroy.js | 2 +- test/parallel/test-async-hooks-http-agent.js | 2 +- .../test-async-hooks-http-parser-destroy.js | 1 + ...test-async-hooks-prevent-double-destroy.js | 2 +- ...test-async-hooks-promise-enable-disable.js | 1 + .../test-async-hooks-promise-triggerid.js | 1 + test/parallel/test-async-hooks-promise.js | 1 + ...c-hooks-recursive-stack-runInAsyncScope.js | 1 + ...oks-run-in-async-scope-caught-exception.js | 1 + ...async-hooks-run-in-async-scope-this-arg.js | 1 + ...async-hooks-stack-overflow-nested-async.js | 2 +- ...st-async-hooks-stack-overflow-try-catch.js | 2 +- .../test-async-hooks-stack-overflow.js | 2 +- ...st-async-hooks-top-level-clearimmediate.js | 1 + test/parallel/test-async-hooks-vm-gc.js | 2 +- ...-async-hooks-worker-asyncfn-terminate-1.js | 1 + ...-async-hooks-worker-asyncfn-terminate-2.js | 1 + ...-async-hooks-worker-asyncfn-terminate-3.js | 1 + ...-async-hooks-worker-asyncfn-terminate-4.js | 1 + ...st-async-local-storage-http-parser-leak.js | 2 +- test/parallel/test-async-wrap-constructor.js | 1 + test/parallel/test-async-wrap-destroyid.js | 2 +- .../test-async-wrap-pop-id-during-load.js | 1 + .../test-async-wrap-promise-after-enabled.js | 1 + .../test-async-wrap-tlssocket-asyncreset.js | 1 + test/parallel/test-async-wrap-trigger-id.js | 1 + .../test-async-wrap-uncaughtexception.js | 1 + test/parallel/test-cli-node-options.js | 4 +- test/parallel/test-common-gc.js | 2 +- .../test-diagnostics-channel-memory-leak.js | 2 +- .../test-emit-after-uncaught-exception.js | 1 + .../test-eventemitter-asyncresource.js | 1 + ...t-fs-cp-async-destination-appears-late.mjs | 1 + .../test-fs-existssync-memleak-longpath.js | 2 +- .../test-fs-readfile-one-roundtrip.js | 1 + .../test-gc-http-client-connaborted.js | 2 +- test/parallel/test-gc-net-timeout.js | 2 +- test/parallel/test-gc-tls-external-memory.js | 2 +- .../test-heapdump-async-hooks-init-promise.js | 2 +- .../test-http-agent-domain-reused-gc.js | 2 +- ...-http-client-leaky-with-double-response.js | 2 +- ...t-http-server-connections-checking-leak.js | 2 +- .../test-http-server-keepalive-req-gc.js | 2 +- ...est-http-uncaught-from-request-callback.js | 1 + test/parallel/test-http2-debug.js | 1 + test/parallel/test-http2-ping.js | 1 + ...-https-server-connections-checking-leak.js | 2 +- test/parallel/test-inspector-contexts.js | 2 +- .../test-inspector-debug-async-hook.js | 1 + .../test-internal-util-weakreference.js | 2 +- test/parallel/test-messageport-hasref.js | 1 + test/parallel/test-net-connect-memleak.js | 2 +- test/parallel/test-primitive-timer-leak.js | 2 +- .../parallel/test-promise-hook-create-hook.js | 1 + ...est-queue-microtask-uncaught-asynchooks.js | 1 + test/parallel/test-shadow-realm-gc-module.js | 2 +- test/parallel/test-shadow-realm-gc.js | 2 +- .../test-source-map-cjs-require-cache.js | 2 +- test/parallel/test-sqlite-session.js | 2 +- ...-stream-finished-bindAsyncResource-path.js | 2 +- .../test-stream-writable-samecb-singletick.js | 1 + test/parallel/test-tls-connect-memleak.js | 2 +- .../test-trace-events-async-hooks-dynamic.js | 2 +- .../test-trace-events-perfetto-pftrace.js | 2 +- test/parallel/test-util-debounce.js | 2 +- test/parallel/test-util-throttle.js | 2 +- test/parallel/test-v8-coverage.js | 1 + test/parallel/test-v8-serialize-leak.js | 2 +- test/parallel/test-worker-hasref.js | 1 + ...r-message-port-inspect-during-init-hook.js | 1 + .../test-worker-messageport-hasref.js | 1 + .../test-zlib-invalid-input-memory.js | 2 +- .../test-async-wrap-getasyncid-tty.js | 2 +- test/sequential/test-async-wrap-getasyncid.js | 2 +- .../sequential/test-gc-http-client-onerror.js | 2 +- .../sequential/test-gc-http-client-timeout.js | 2 +- test/sequential/test-gc-http-client.js | 2 +- test/trace_events/test-trace-events-all.js | 2 +- .../test-trace-events-async-hooks-worker.js | 2 +- .../test-trace-events-async-hooks.js | 2 +- .../test-trace-events-file-pattern.js | 1 + .../test-trace-events-process-exit.js | 2 +- 196 files changed, 444 insertions(+), 86 deletions(-) create mode 100644 test/parallel/test-async-hooks-create-hook-disabled-internals.js create mode 100644 test/parallel/test-async-hooks-create-hook-disabled.js create mode 100644 test/parallel/test-async-hooks-create-hook-enabled.js diff --git a/doc/api/cli.md b/doc/api/cli.md index bddd4a5c0a5f..b6e05e57316a 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -139,6 +139,46 @@ Error: Cannot load native addon because loading addons is disabled. } ``` +### `--enable-async-hooks` + + + +Enable use of `async_hooks.createHook()`. This flag is required to enable +the `createHook` API, which is disabled by default. + +Example: + +```mjs +import { createHook } from 'node:async_hooks'; + +createHook({ init() {} }).enable(); +``` + +```cjs +const { createHook } = require('node:async_hooks'); + +createHook({ init() {} }).enable(); +``` + +```console +$ node index.js +node:async_hooks:160 + throw new ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED(); + ^ + +Error [ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED]: async_hooks.createHook() is disabled. Use --enable-async-hooks to enable it. + at createHook (node:async_hooks:160:11) + at Object. (/home/user/index.js:3:1) + ... +``` + +```console +$ node --enable-async-hooks index.js +# Works without error +``` + ### `--allow-child-process` * `--allow-addons` +* `--enable-async-hooks` * `--allow-child-process` * `--allow-env` * `--allow-ffi` diff --git a/doc/api/errors.md b/doc/api/errors.md index 2a1e423d10dc..c25838ca7b68 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -733,6 +733,17 @@ by the `node:assert` module. An attempt was made to register something that is not a function as an `AsyncHooks` callback. + + +### `ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED` + + + +An attempt was made to call [`async_hooks.createHook()`][] without the +[`--enable-async-hooks`][] flag. + ### `ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED` @@ -4773,6 +4784,7 @@ An error occurred trying to allocate memory. This should never happen. [`"exports"`]: packages.md#exports [`"imports"`]: packages.md#imports [`'uncaughtException'`]: process.md#event-uncaughtexception +[`--enable-async-hooks`]: cli.md#--enable-async-hooks [`--disable-proto=throw`]: cli.md#--disable-protomode [`--force-fips`]: cli.md#--force-fips [`--no-addons`]: cli.md#--no-addons @@ -4798,6 +4810,7 @@ An error occurred trying to allocate memory. This should never happen. [`Writable`]: stream.md#class-streamwritable [`ZipBuffer`]: zlib.md#class-zlibzipbuffer [`ZipFile`]: zlib.md#class-zlibzipfile +[`async_hooks.createHook()`]: async_hooks.md#async_hookscreatehookoptions [`child_process`]: child_process.md [`cipher.getAuthTag()`]: crypto.md#ciphergetauthtag [`crypto.getDiffieHellman()`]: crypto.md#cryptogetdiffiehellmangroupname diff --git a/doc/node.1 b/doc/node.1 index 7a32ece46d21..2d5a3b98efc0 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -86,6 +86,36 @@ Error: Cannot load native addon because loading addons is disabled. } .Ed . +.It Fl -enable-async-hooks +Enable use of \fBasync_hooks.createHook()\fR. This flag is required to enable +the \fBcreateHook\fR API, which is disabled by default. +Example: +.Bd -literal +import { createHook } from 'node:async_hooks'; + +createHook({ init() {} }).enable(); +.Ed +.Bd -literal +const { createHook } = require('node:async_hooks'); + +createHook({ init() {} }).enable(); +.Ed +.Bd -literal +$ node index.js +node:async_hooks:160 + throw new ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED(); + ^ + +Error [ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED]: async_hooks.createHook() is disabled. Use --enable-async-hooks to enable it. + at createHook (node:async_hooks:160:11) + at Object. (/home/user/index.js:3:1) + ... +.Ed +.Bd -literal +$ node --enable-async-hooks index.js +# Works without error +.Ed +. .It Fl -allow-child-process When using the Permission Model, the process will not be able to spawn any child process by default. @@ -2186,6 +2216,8 @@ one is included in the list below. .It \fB--allow-addons\fR .It +\fB--enable-async-hooks\fR +.It \fB--allow-child-process\fR .It \fB--allow-env\fR diff --git a/lib/async_hooks.js b/lib/async_hooks.js index b0106020d64c..16899b1c1c5f 100644 --- a/lib/async_hooks.js +++ b/lib/async_hooks.js @@ -16,11 +16,13 @@ const { const { ERR_ASYNC_CALLBACK, + ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED, ERR_ASYNC_RESOURCE_DOMAIN_REMOVED, ERR_ASYNC_TYPE, ERR_INVALID_ASYNC_ID, ERR_INVALID_ARG_VALUE, } = require('internal/errors').codes; +const { getOptionValue } = require('internal/options'); const { kEmptyObject, } = require('internal/util'); @@ -168,6 +170,9 @@ class AsyncHook { function createHook(fns) { + if (!getOptionValue('--enable-async-hooks')) { + throw new ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED(); + } return new AsyncHook(fns); } diff --git a/lib/internal/async_hooks.js b/lib/internal/async_hooks.js index 8a60b9a6ce52..01b232ac2a82 100644 --- a/lib/internal/async_hooks.js +++ b/lib/internal/async_hooks.js @@ -1,7 +1,11 @@ 'use strict'; const { + ArrayPrototypeIncludes, + ArrayPrototypeIndexOf, + ArrayPrototypePush, ArrayPrototypeSlice, + ArrayPrototypeSplice, ErrorCaptureStackTrace, ObjectDefineProperty, ObjectPrototypeHasOwnProperty, @@ -10,6 +14,7 @@ const { } = primordials; const { exitCodes: { kGenericUserError } } = internalBinding('errors'); +const { ERR_ASYNC_CALLBACK } = require('internal/errors').codes; const async_wrap = internalBinding('async_wrap'); const { setCallbackTrampoline } = async_wrap; @@ -576,9 +581,83 @@ function triggerAsyncId() { const kNoPromiseHook = Symbol('kNoPromiseHook'); +// Minimal internal async hook used by Node.js internals (e.g. the inspector) +// that must create hooks without --enable-async-hooks. Unlike the public +// async_hooks.createHook() this does not support promise callbacks. +class AsyncHook { + constructor({ init, before, after, destroy }) { + if (init !== undefined && typeof init !== 'function') + throw new ERR_ASYNC_CALLBACK('hook.init'); + if (before !== undefined && typeof before !== 'function') + throw new ERR_ASYNC_CALLBACK('hook.before'); + if (after !== undefined && typeof after !== 'function') + throw new ERR_ASYNC_CALLBACK('hook.after'); + if (destroy !== undefined && typeof destroy !== 'function') + throw new ERR_ASYNC_CALLBACK('hook.destroy'); + + // Internal hooks never track promises. + this[kNoPromiseHook] = true; + this[init_symbol] = init; + this[before_symbol] = before; + this[after_symbol] = after; + this[destroy_symbol] = destroy; + } + + enable() { + const { 0: hooks_array, 1: hook_fields } = getHookArrays(); + + if (ArrayPrototypeIncludes(hooks_array, this)) + return this; + + const prev_kTotals = hook_fields[kTotals]; + + hook_fields[kTotals] = hook_fields[kInit] += +!!this[init_symbol]; + hook_fields[kTotals] += hook_fields[kBefore] += +!!this[before_symbol]; + hook_fields[kTotals] += hook_fields[kAfter] += +!!this[after_symbol]; + hook_fields[kTotals] += hook_fields[kDestroy] += +!!this[destroy_symbol]; + ArrayPrototypePush(hooks_array, this); + + if (prev_kTotals === 0 && hook_fields[kTotals] > 0) { + enableHooks(); + } + + return this; + } + + disable() { + const { 0: hooks_array, 1: hook_fields } = getHookArrays(); + + const index = ArrayPrototypeIndexOf(hooks_array, this); + if (index === -1) + return this; + + const prev_kTotals = hook_fields[kTotals]; + + hook_fields[kTotals] = hook_fields[kInit] -= +!!this[init_symbol]; + hook_fields[kTotals] += hook_fields[kBefore] -= +!!this[before_symbol]; + hook_fields[kTotals] += hook_fields[kAfter] -= +!!this[after_symbol]; + hook_fields[kTotals] += hook_fields[kDestroy] -= +!!this[destroy_symbol]; + ArrayPrototypeSplice(hooks_array, index, 1); + + if (prev_kTotals > 0 && hook_fields[kTotals] === 0) { + disableHooks(); + } + + return this; + } +} + +// Creates an internal AsyncHook without honoring --enable-async-hooks. Only for +// use by Node.js internals; userland goes through async_hooks.createHook(). +function createHook(fns) { + return new AsyncHook(fns); +} + module.exports = { executionAsyncId, triggerAsyncId, + // Create an async hook without honoring --enable-async-hooks (internals only). + createHook, // Private API getHookArrays, symbols: { diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 88c4102eee4f..b08b99c0227e 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1143,6 +1143,8 @@ E('ERR_AMBIGUOUS_ARGUMENT', 'The "%s" argument is ambiguous. %s', TypeError); E('ERR_ARG_NOT_ITERABLE', '%s must be iterable', TypeError); E('ERR_ASSERTION', '%s', Error); E('ERR_ASYNC_CALLBACK', '%s must be a function', TypeError); +E('ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED', + 'async_hooks.createHook() is disabled. Use --enable-async-hooks to enable it.', Error); E('ERR_ASYNC_LOADER_REQUEST_NEVER_SETTLED', 'Async loader request never settled', Error); E('ERR_ASYNC_RESOURCE_DOMAIN_REMOVED', diff --git a/lib/internal/inspector_async_hook.js b/lib/internal/inspector_async_hook.js index 8ab833ea8ef1..4bafef870b78 100644 --- a/lib/internal/inspector_async_hook.js +++ b/lib/internal/inspector_async_hook.js @@ -5,7 +5,7 @@ let config; function lazyHookCreation() { const inspector = internalBinding('inspector'); - const { createHook } = require('async_hooks'); + const { createHook } = require('internal/async_hooks'); config = internalBinding('config'); hook = createHook({ diff --git a/src/node_options.cc b/src/node_options.cc index 4ba4801ad1dc..17a1acbdc9f2 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -947,6 +947,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { kAllowedInEnvvar, false, OptionNamespaces::kPermissionNamespace); + AddOption("--enable-async-hooks", + "enable use of async_hooks.createHook", + BOOL_FIELD(enable_async_hooks), + kAllowedInEnvvar); AddOption("--allow-openssl-store", "allow use of OpenSSL STORE loaders when any permissions are set", BOOL_FIELD(allow_openssl_store), diff --git a/src/node_options.h b/src/node_options.h index f8aa58253862..3021dd230e09 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -238,6 +238,7 @@ class EnvironmentOptions : public Options { DEFINE_BOOL_FIELD(allow_ffi) = false; DEFINE_BOOL_FIELD(allow_openssl_store) = false; DEFINE_BOOL_FIELD(allow_worker_threads) = false; + DEFINE_BOOL_FIELD(enable_async_hooks) = false; DEFINE_BOOL_FIELD(experimental_vm_modules) = EXPERIMENTALS_DEFAULT_VALUE; DEFINE_BOOL_FIELD(expose_internals) = false; DEFINE_BOOL_FIELD(force_node_api_uncaught_exceptions_policy) = false; diff --git a/test/addons/async-resource/test.js b/test/addons/async-resource/test.js index d7bc44a92be8..5a9b9e6f4255 100644 --- a/test/addons/async-resource/test.js +++ b/test/addons/async-resource/test.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../../common'); const assert = require('assert'); diff --git a/test/addons/callback-scope/test-async-hooks.js b/test/addons/callback-scope/test-async-hooks.js index 2d1c8719b345..5801fcd18b4b 100644 --- a/test/addons/callback-scope/test-async-hooks.js +++ b/test/addons/callback-scope/test-async-hooks.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../../common'); const assert = require('assert'); diff --git a/test/async-hooks/init-hooks.js b/test/async-hooks/init-hooks.js index 8fc44994fbc4..24b353fc6253 100644 --- a/test/async-hooks/init-hooks.js +++ b/test/async-hooks/init-hooks.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-async-await.js b/test/async-hooks/test-async-await.js index 4fd698c8e981..d05075373cb8 100644 --- a/test/async-hooks/test-async-await.js +++ b/test/async-hooks/test-async-await.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); // This test ensures async hooks are being properly called diff --git a/test/async-hooks/test-async-exec-resource-http-32060.js b/test/async-hooks/test-async-exec-resource-http-32060.js index 35869708dfc1..c5ae3bb7a977 100644 --- a/test/async-hooks/test-async-exec-resource-http-32060.js +++ b/test/async-hooks/test-async-exec-resource-http-32060.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const { diff --git a/test/async-hooks/test-async-exec-resource-http-agent.js b/test/async-hooks/test-async-exec-resource-http-agent.js index abc2df3a1930..fc919af4eb5d 100644 --- a/test/async-hooks/test-async-exec-resource-http-agent.js +++ b/test/async-hooks/test-async-exec-resource-http-agent.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); diff --git a/test/async-hooks/test-async-exec-resource-http.js b/test/async-hooks/test-async-exec-resource-http.js index 0615a404045a..05bdc014dba2 100644 --- a/test/async-hooks/test-async-exec-resource-http.js +++ b/test/async-hooks/test-async-exec-resource-http.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-async-exec-resource-match.js b/test/async-hooks/test-async-exec-resource-match.js index 0b68b30ffa93..a94ecfa2e413 100644 --- a/test/async-hooks/test-async-exec-resource-match.js +++ b/test/async-hooks/test-async-exec-resource-match.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-async-local-storage-gcable.js b/test/async-hooks/test-async-local-storage-gcable.js index 303442e60c88..ee81250856db 100644 --- a/test/async-hooks/test-async-local-storage-gcable.js +++ b/test/async-hooks/test-async-local-storage-gcable.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose_gc +// Flags: --enable-async-hooks --expose_gc // This test ensures that AsyncLocalStorage gets gced once it was disabled // and no strong references remain in userland. diff --git a/test/async-hooks/test-callback-error.js b/test/async-hooks/test-callback-error.js index ad70feb70c95..5e42ba5b3f07 100644 --- a/test/async-hooks/test-callback-error.js +++ b/test/async-hooks/test-callback-error.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const { spawnSync } = require('child_process'); @@ -37,7 +38,7 @@ assert.ok(!arg); // console.log should stay until this test's flakiness is solved console.log('start case 1'); console.time('end case 1'); - const child = spawnSync(process.execPath, [__filename, 'test_init_callback']); + const child = spawnSync(process.execPath, ['--enable-async-hooks', __filename, 'test_init_callback']); assert.ifError(child.error); const test_init_first_line = child.stderr.toString().split(/[\r\n]+/g)[0]; assert.strictEqual(test_init_first_line, 'Error: test_init_callback'); @@ -48,7 +49,7 @@ assert.ok(!arg); { console.log('start case 2'); console.time('end case 2'); - const child = spawnSync(process.execPath, [__filename, 'test_callback']); + const child = spawnSync(process.execPath, ['--enable-async-hooks', __filename, 'test_callback']); assert.ifError(child.error); const test_callback_first_line = child.stderr.toString().split(/[\r\n]+/g)[0]; assert.strictEqual(test_callback_first_line, 'Error: test_callback'); @@ -61,10 +62,10 @@ assert.ok(!arg); console.time('end case 3'); let program = process.execPath; let args = [ - '--abort-on-uncaught-exception', __filename, 'test_callback_abort' ]; + '--enable-async-hooks', '--abort-on-uncaught-exception', __filename, 'test_callback_abort' ]; let options = {}; if (!common.isWindows) { - [program, options] = common.escapePOSIXShell`ulimit -c 0 && exec "${program}" ${args[0]} "${args[1]}" ${args[2]}`; + [program, options] = common.escapePOSIXShell`ulimit -c 0 && exec "${program}" ${args[0]} ${args[1]} "${args[2]}" ${args[3]}`; args = []; options.shell = true; } diff --git a/test/async-hooks/test-crypto-pbkdf2.js b/test/async-hooks/test-crypto-pbkdf2.js index c607adf72587..e6f9c7cc2459 100644 --- a/test/async-hooks/test-crypto-pbkdf2.js +++ b/test/async-hooks/test-crypto-pbkdf2.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasCrypto) { diff --git a/test/async-hooks/test-crypto-randomBytes.js b/test/async-hooks/test-crypto-randomBytes.js index 8ecc1c45a9a5..2213d08f3dc2 100644 --- a/test/async-hooks/test-crypto-randomBytes.js +++ b/test/async-hooks/test-crypto-randomBytes.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasCrypto) { diff --git a/test/async-hooks/test-destroy-not-blocked.js b/test/async-hooks/test-destroy-not-blocked.js index 2bbddf3047bb..38541eb9f528 100644 --- a/test/async-hooks/test-destroy-not-blocked.js +++ b/test/async-hooks/test-destroy-not-blocked.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose_gc +// Flags: --enable-async-hooks --expose_gc const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-disable-in-init.js b/test/async-hooks/test-disable-in-init.js index f810dfca3b96..32cc2622fa48 100644 --- a/test/async-hooks/test-disable-in-init.js +++ b/test/async-hooks/test-disable-in-init.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const async_hooks = require('async_hooks'); diff --git a/test/async-hooks/test-embedder.api.async-resource-no-type.js b/test/async-hooks/test-embedder.api.async-resource-no-type.js index e21c5458df86..60050c339507 100644 --- a/test/async-hooks/test-embedder.api.async-resource-no-type.js +++ b/test/async-hooks/test-embedder.api.async-resource-no-type.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); @@ -25,7 +26,7 @@ if (process.argv[2] === 'child') { }); } else { - const args = process.argv.slice(1).concat('child'); + const args = ['--enable-async-hooks', ...process.argv.slice(1), 'child']; spawn(process.execPath, args) .on('close', common.mustCall((code) => { // No error because the type was defaulted diff --git a/test/async-hooks/test-embedder.api.async-resource.js b/test/async-hooks/test-embedder.api.async-resource.js index d60c03fb87b2..1b10c05470d3 100644 --- a/test/async-hooks/test-embedder.api.async-resource.js +++ b/test/async-hooks/test-embedder.api.async-resource.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-emit-after-on-destroyed.js b/test/async-hooks/test-emit-after-on-destroyed.js index 719d6ab91a54..8595caaff087 100644 --- a/test/async-hooks/test-emit-after-on-destroyed.js +++ b/test/async-hooks/test-emit-after-on-destroyed.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; const common = require('../common'); @@ -42,7 +42,7 @@ if (process.argv[2] === 'child') { emitAfter(asyncId); } } else { - const args = ['--expose-internals'] + const args = ['--enable-async-hooks', '--expose-internals'] .concat(process.argv.slice(1)) .concat('child'); let errData = Buffer.from(''); diff --git a/test/async-hooks/test-emit-before-after.js b/test/async-hooks/test-emit-before-after.js index 561004cac2f0..75c7e2267832 100644 --- a/test/async-hooks/test-emit-before-after.js +++ b/test/async-hooks/test-emit-before-after.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-emit-before-on-destroyed.js b/test/async-hooks/test-emit-before-on-destroyed.js index ca0553e53348..7b367d7f8e99 100644 --- a/test/async-hooks/test-emit-before-on-destroyed.js +++ b/test/async-hooks/test-emit-before-on-destroyed.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; const common = require('../common'); @@ -42,7 +42,7 @@ if (process.argv[2] === 'child') { emitBefore(asyncId, triggerId); } } else { - const args = ['--expose-internals'] + const args = ['--enable-async-hooks', '--expose-internals'] .concat(process.argv.slice(1)) .concat('child'); let errData = Buffer.from(''); diff --git a/test/async-hooks/test-emit-init.js b/test/async-hooks/test-emit-init.js index 8994943b4729..7e6f2e2deddc 100644 --- a/test/async-hooks/test-emit-init.js +++ b/test/async-hooks/test-emit-init.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-enable-disable.js b/test/async-hooks/test-enable-disable.js index d408338e892c..257752ac9be4 100644 --- a/test/async-hooks/test-enable-disable.js +++ b/test/async-hooks/test-enable-disable.js @@ -81,6 +81,7 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-enable-in-init.js b/test/async-hooks/test-enable-in-init.js index e710657a3404..0fee0d1bd196 100644 --- a/test/async-hooks/test-enable-in-init.js +++ b/test/async-hooks/test-enable-in-init.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const async_hooks = require('async_hooks'); diff --git a/test/async-hooks/test-filehandle-no-reuse.js b/test/async-hooks/test-filehandle-no-reuse.js index f607a7a22e08..7486405e8fcb 100644 --- a/test/async-hooks/test-filehandle-no-reuse.js +++ b/test/async-hooks/test-filehandle-no-reuse.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const initHooks = require('./init-hooks'); diff --git a/test/async-hooks/test-fseventwrap.js b/test/async-hooks/test-fseventwrap.js index a5e1a3b9d2f2..5c705564bc4f 100644 --- a/test/async-hooks/test-fseventwrap.js +++ b/test/async-hooks/test-fseventwrap.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-fsreqcallback-access.js b/test/async-hooks/test-fsreqcallback-access.js index b1b75f569305..5bdc605101a7 100644 --- a/test/async-hooks/test-fsreqcallback-access.js +++ b/test/async-hooks/test-fsreqcallback-access.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-fsreqcallback-readFile.js b/test/async-hooks/test-fsreqcallback-readFile.js index fb84306cfa86..ce42224bbb5d 100644 --- a/test/async-hooks/test-fsreqcallback-readFile.js +++ b/test/async-hooks/test-fsreqcallback-readFile.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-getaddrinforeqwrap.js b/test/async-hooks/test-getaddrinforeqwrap.js index a21557bcd56e..9505ae9d3963 100644 --- a/test/async-hooks/test-getaddrinforeqwrap.js +++ b/test/async-hooks/test-getaddrinforeqwrap.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-getnameinforeqwrap.js b/test/async-hooks/test-getnameinforeqwrap.js index b00fa0d4d9dd..71bb868304a7 100644 --- a/test/async-hooks/test-getnameinforeqwrap.js +++ b/test/async-hooks/test-getnameinforeqwrap.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-graph.fsreq-readFile.js b/test/async-hooks/test-graph.fsreq-readFile.js index 39435cdc4891..f1722d0e0c41 100644 --- a/test/async-hooks/test-graph.fsreq-readFile.js +++ b/test/async-hooks/test-graph.fsreq-readFile.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const initHooks = require('./init-hooks'); diff --git a/test/async-hooks/test-graph.http.js b/test/async-hooks/test-graph.http.js index 859000b14aa8..03fdfc04c37f 100644 --- a/test/async-hooks/test-graph.http.js +++ b/test/async-hooks/test-graph.http.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasIPv6) diff --git a/test/async-hooks/test-graph.intervals.js b/test/async-hooks/test-graph.intervals.js index 9e626951a14b..f63e186bbc1c 100644 --- a/test/async-hooks/test-graph.intervals.js +++ b/test/async-hooks/test-graph.intervals.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const initHooks = require('./init-hooks'); diff --git a/test/async-hooks/test-graph.pipe.js b/test/async-hooks/test-graph.pipe.js index abf8a98ff00e..36200af616fd 100644 --- a/test/async-hooks/test-graph.pipe.js +++ b/test/async-hooks/test-graph.pipe.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const initHooks = require('./init-hooks'); diff --git a/test/async-hooks/test-graph.pipeconnect.js b/test/async-hooks/test-graph.pipeconnect.js index db237ff6b2d0..1dca97abbf2a 100644 --- a/test/async-hooks/test-graph.pipeconnect.js +++ b/test/async-hooks/test-graph.pipeconnect.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const initHooks = require('./init-hooks'); diff --git a/test/async-hooks/test-graph.shutdown.js b/test/async-hooks/test-graph.shutdown.js index 0f633787e5e5..e165a0405c30 100644 --- a/test/async-hooks/test-graph.shutdown.js +++ b/test/async-hooks/test-graph.shutdown.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasIPv6) diff --git a/test/async-hooks/test-graph.signal.js b/test/async-hooks/test-graph.signal.js index 351fb7550af4..589a00322011 100644 --- a/test/async-hooks/test-graph.signal.js +++ b/test/async-hooks/test-graph.signal.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (common.isWindows) { diff --git a/test/async-hooks/test-graph.statwatcher.js b/test/async-hooks/test-graph.statwatcher.js index f960ffebd3eb..aac1fe431863 100644 --- a/test/async-hooks/test-graph.statwatcher.js +++ b/test/async-hooks/test-graph.statwatcher.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks require('../common'); const commonPath = require.resolve('../common'); diff --git a/test/async-hooks/test-graph.tcp.js b/test/async-hooks/test-graph.tcp.js index 6f8db20add68..43bb18414bef 100644 --- a/test/async-hooks/test-graph.tcp.js +++ b/test/async-hooks/test-graph.tcp.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasIPv6) diff --git a/test/async-hooks/test-graph.timeouts.js b/test/async-hooks/test-graph.timeouts.js index 88350db2bae8..031020d6f46c 100644 --- a/test/async-hooks/test-graph.timeouts.js +++ b/test/async-hooks/test-graph.timeouts.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const initHooks = require('./init-hooks'); diff --git a/test/async-hooks/test-graph.tls-write-12.js b/test/async-hooks/test-graph.tls-write-12.js index 748234402c0e..621c085faabe 100644 --- a/test/async-hooks/test-graph.tls-write-12.js +++ b/test/async-hooks/test-graph.tls-write-12.js @@ -1,3 +1,4 @@ +// Flags: --enable-async-hooks 'use strict'; const common = require('../common'); diff --git a/test/async-hooks/test-graph.tls-write.js b/test/async-hooks/test-graph.tls-write.js index 243039e01d11..bb71c01ebacc 100644 --- a/test/async-hooks/test-graph.tls-write.js +++ b/test/async-hooks/test-graph.tls-write.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasCrypto) diff --git a/test/async-hooks/test-http-agent-handle-reuse-parallel.js b/test/async-hooks/test-http-agent-handle-reuse-parallel.js index 3827691cc8bc..cdabb7b4b423 100644 --- a/test/async-hooks/test-http-agent-handle-reuse-parallel.js +++ b/test/async-hooks/test-http-agent-handle-reuse-parallel.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals const common = require('../common'); const initHooks = require('./init-hooks'); const { checkInvocations } = require('./hook-checks'); diff --git a/test/async-hooks/test-http-agent-handle-reuse-serial.js b/test/async-hooks/test-http-agent-handle-reuse-serial.js index bae0698a0a6b..50974fc254fa 100644 --- a/test/async-hooks/test-http-agent-handle-reuse-serial.js +++ b/test/async-hooks/test-http-agent-handle-reuse-serial.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals const common = require('../common'); const initHooks = require('./init-hooks'); const { checkInvocations } = require('./hook-checks'); diff --git a/test/async-hooks/test-httpparser-reuse.js b/test/async-hooks/test-httpparser-reuse.js index f7ce2cd87622..29b6a94e92bd 100644 --- a/test/async-hooks/test-httpparser-reuse.js +++ b/test/async-hooks/test-httpparser-reuse.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-httpparser.request.js b/test/async-hooks/test-httpparser.request.js index 6379bf330d23..c7b00130e160 100644 --- a/test/async-hooks/test-httpparser.request.js +++ b/test/async-hooks/test-httpparser.request.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals --no-warnings +// Flags: --enable-async-hooks --expose-internals --no-warnings 'use strict'; diff --git a/test/async-hooks/test-httpparser.response.js b/test/async-hooks/test-httpparser.response.js index 2e600b127475..1493fbe4d8b1 100644 --- a/test/async-hooks/test-httpparser.response.js +++ b/test/async-hooks/test-httpparser.response.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals --no-warnings +// Flags: --enable-async-hooks --expose-internals --no-warnings 'use strict'; diff --git a/test/async-hooks/test-immediate.js b/test/async-hooks/test-immediate.js index fa9475abaed2..657b0d028d89 100644 --- a/test/async-hooks/test-immediate.js +++ b/test/async-hooks/test-immediate.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-improper-order.js b/test/async-hooks/test-improper-order.js index 47678fb19777..13245e8a24d6 100644 --- a/test/async-hooks/test-improper-order.js +++ b/test/async-hooks/test-improper-order.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; const common = require('../common'); @@ -41,7 +41,7 @@ if (process.argv[2] === 'child') { emitAfter(asyncId); } } else { - const args = ['--expose-internals'] + const args = ['--enable-async-hooks', '--expose-internals'] .concat(process.argv.slice(1)) .concat('child'); let errData = Buffer.from(''); diff --git a/test/async-hooks/test-improper-unwind.js b/test/async-hooks/test-improper-unwind.js index 9e651b3bc50f..3de183852a42 100644 --- a/test/async-hooks/test-improper-unwind.js +++ b/test/async-hooks/test-improper-unwind.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; const common = require('../common'); @@ -45,7 +45,7 @@ if (process.argv[2] === 'child') { console.log('heartbeat: still alive'); emitAfter(eventOneId); } else { - const args = ['--expose-internals'] + const args = ['--enable-async-hooks', '--expose-internals'] .concat(process.argv.slice(1)) .concat('child'); let errData = Buffer.from(''); diff --git a/test/async-hooks/test-late-hook-enable.js b/test/async-hooks/test-late-hook-enable.js index 3305a05065b6..a84eb625b2b2 100644 --- a/test/async-hooks/test-late-hook-enable.js +++ b/test/async-hooks/test-late-hook-enable.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/async-hooks/test-nexttick-default-trigger.js b/test/async-hooks/test-nexttick-default-trigger.js index fa1ad2c561ce..ebdf996b58e9 100644 --- a/test/async-hooks/test-nexttick-default-trigger.js +++ b/test/async-hooks/test-nexttick-default-trigger.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); // This tests ensures that the triggerId of the nextTick function sets the diff --git a/test/async-hooks/test-pipeconnectwrap.js b/test/async-hooks/test-pipeconnectwrap.js index 36980f018598..d23ef20b5074 100644 --- a/test/async-hooks/test-pipeconnectwrap.js +++ b/test/async-hooks/test-pipeconnectwrap.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-pipewrap.js b/test/async-hooks/test-pipewrap.js index 7ea5f38adc85..45eae3fd8995 100644 --- a/test/async-hooks/test-pipewrap.js +++ b/test/async-hooks/test-pipewrap.js @@ -1,7 +1,7 @@ // NOTE: this also covers process wrap as one is created along with the pipes // when we launch the sleep process 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-promise.chain-promise-before-init-hooks.js b/test/async-hooks/test-promise.chain-promise-before-init-hooks.js index f292c8286572..ee4a7b85a55b 100644 --- a/test/async-hooks/test-promise.chain-promise-before-init-hooks.js +++ b/test/async-hooks/test-promise.chain-promise-before-init-hooks.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-promise.js b/test/async-hooks/test-promise.js index 96be5e5efcb4..9ff89658315d 100644 --- a/test/async-hooks/test-promise.js +++ b/test/async-hooks/test-promise.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); diff --git a/test/async-hooks/test-promise.promise-before-init-hooks.js b/test/async-hooks/test-promise.promise-before-init-hooks.js index b61a214f4289..1a5e59273617 100644 --- a/test/async-hooks/test-promise.promise-before-init-hooks.js +++ b/test/async-hooks/test-promise.promise-before-init-hooks.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-querywrap.js b/test/async-hooks/test-querywrap.js index 5ddb2fe700ef..9cdda6eaa3a6 100644 --- a/test/async-hooks/test-querywrap.js +++ b/test/async-hooks/test-querywrap.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-queue-microtask.js b/test/async-hooks/test-queue-microtask.js index 01200d454239..c20cc72eb8df 100644 --- a/test/async-hooks/test-queue-microtask.js +++ b/test/async-hooks/test-queue-microtask.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-shutdownwrap.js b/test/async-hooks/test-shutdownwrap.js index fea4a3a166a2..0d1c44924d34 100644 --- a/test/async-hooks/test-shutdownwrap.js +++ b/test/async-hooks/test-shutdownwrap.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-signalwrap.js b/test/async-hooks/test-signalwrap.js index 60adaedd476f..ec140eefe0d3 100644 --- a/test/async-hooks/test-signalwrap.js +++ b/test/async-hooks/test-signalwrap.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (common.isWindows) { diff --git a/test/async-hooks/test-statwatcher.js b/test/async-hooks/test-statwatcher.js index d24aab584029..8e2233113538 100644 --- a/test/async-hooks/test-statwatcher.js +++ b/test/async-hooks/test-statwatcher.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const tmpdir = require('../common/tmpdir'); diff --git a/test/async-hooks/test-tcpwrap.js b/test/async-hooks/test-tcpwrap.js index 3f0987b98822..177e27e1b91a 100644 --- a/test/async-hooks/test-tcpwrap.js +++ b/test/async-hooks/test-tcpwrap.js @@ -1,5 +1,6 @@ // Covers TCPWRAP and related TCPCONNECTWRAP 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasIPv6) diff --git a/test/async-hooks/test-timers.setInterval.js b/test/async-hooks/test-timers.setInterval.js index 10b2bafb2a25..a46cc46fa628 100644 --- a/test/async-hooks/test-timers.setInterval.js +++ b/test/async-hooks/test-timers.setInterval.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-timers.setTimeout.js b/test/async-hooks/test-timers.setTimeout.js index 540c88abade3..288c0c691216 100644 --- a/test/async-hooks/test-timers.setTimeout.js +++ b/test/async-hooks/test-timers.setTimeout.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-tlswrap.js b/test/async-hooks/test-tlswrap.js index 6a8996e00f2b..c9ac56522b6f 100644 --- a/test/async-hooks/test-tlswrap.js +++ b/test/async-hooks/test-tlswrap.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasCrypto) diff --git a/test/async-hooks/test-track-promises-default.js b/test/async-hooks/test-track-promises-default.js index 071f8faaecc7..7440d5a1a699 100644 --- a/test/async-hooks/test-track-promises-default.js +++ b/test/async-hooks/test-track-promises-default.js @@ -1,3 +1,4 @@ +// Flags: --enable-async-hooks 'use strict'; // Test that trackPromises default to true. const common = require('../common'); diff --git a/test/async-hooks/test-track-promises-false-check.js b/test/async-hooks/test-track-promises-false-check.js index 7ff4142d0d1f..7fb059af1e11 100644 --- a/test/async-hooks/test-track-promises-false-check.js +++ b/test/async-hooks/test-track-promises-false-check.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; // Test that trackPromises: false prevents promise hooks from being installed. diff --git a/test/async-hooks/test-track-promises-false.js b/test/async-hooks/test-track-promises-false.js index 1a3b5eda2e2f..2a753ede0359 100644 --- a/test/async-hooks/test-track-promises-false.js +++ b/test/async-hooks/test-track-promises-false.js @@ -1,3 +1,4 @@ +// Flags: --enable-async-hooks 'use strict'; // Test that trackPromises: false works. const common = require('../common'); diff --git a/test/async-hooks/test-track-promises-true.js b/test/async-hooks/test-track-promises-true.js index cc53f3a9c926..8f11eab4a275 100644 --- a/test/async-hooks/test-track-promises-true.js +++ b/test/async-hooks/test-track-promises-true.js @@ -1,3 +1,4 @@ +// Flags: --enable-async-hooks 'use strict'; // Test that trackPromises: true works. const common = require('../common'); diff --git a/test/async-hooks/test-track-promises-validation.js b/test/async-hooks/test-track-promises-validation.js index 108f82ff2562..c7ed7465b334 100644 --- a/test/async-hooks/test-track-promises-validation.js +++ b/test/async-hooks/test-track-promises-validation.js @@ -1,3 +1,4 @@ +// Flags: --enable-async-hooks 'use strict'; // Test validation of trackPromises option. diff --git a/test/async-hooks/test-ttywrap.readstream.js b/test/async-hooks/test-ttywrap.readstream.js index 7e27ffc5bfb2..1cb021092186 100644 --- a/test/async-hooks/test-ttywrap.readstream.js +++ b/test/async-hooks/test-ttywrap.readstream.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-udpsendwrap.js b/test/async-hooks/test-udpsendwrap.js index f1403e3226a1..c1772e4b10aa 100644 --- a/test/async-hooks/test-udpsendwrap.js +++ b/test/async-hooks/test-udpsendwrap.js @@ -1,4 +1,4 @@ -// Flags: --test-udp-no-try-send +// Flags: --enable-async-hooks --test-udp-no-try-send 'use strict'; const common = require('../common'); diff --git a/test/async-hooks/test-udpwrap.js b/test/async-hooks/test-udpwrap.js index 0a0e03c5d514..b8bb97a5bcef 100644 --- a/test/async-hooks/test-udpwrap.js +++ b/test/async-hooks/test-udpwrap.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-unhandled-exception-valid-ids.js b/test/async-hooks/test-unhandled-exception-valid-ids.js index 09e5823452fd..367ba4e6577f 100644 --- a/test/async-hooks/test-unhandled-exception-valid-ids.js +++ b/test/async-hooks/test-unhandled-exception-valid-ids.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const initHooks = require('./init-hooks'); diff --git a/test/async-hooks/test-unhandled-rejection-context.js b/test/async-hooks/test-unhandled-rejection-context.js index 168b51a3331f..c2e8b5fb52bd 100644 --- a/test/async-hooks/test-unhandled-rejection-context.js +++ b/test/async-hooks/test-unhandled-rejection-context.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); diff --git a/test/async-hooks/test-writewrap.js b/test/async-hooks/test-writewrap.js index 4f3455480ba8..62b6254b5a81 100644 --- a/test/async-hooks/test-writewrap.js +++ b/test/async-hooks/test-writewrap.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/async-hooks/test-zlib.zlib-binding.deflate.js b/test/async-hooks/test-zlib.zlib-binding.deflate.js index 802f09eb306c..24bc53dccb92 100644 --- a/test/async-hooks/test-zlib.zlib-binding.deflate.js +++ b/test/async-hooks/test-zlib.zlib-binding.deflate.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; const common = require('../common'); diff --git a/test/es-module/test-vm-compile-function-leak.js b/test/es-module/test-vm-compile-function-leak.js index f9f04588fdc7..a544586a65ec 100644 --- a/test/es-module/test-vm-compile-function-leak.js +++ b/test/es-module/test-vm-compile-function-leak.js @@ -1,4 +1,4 @@ -// Flags: --max-old-space-size=16 --trace-gc +// Flags: --enable-async-hooks --max-old-space-size=16 --trace-gc 'use strict'; // This tests that vm.compileFunction with dynamic import callback does not leak. diff --git a/test/es-module/test-vm-contextified-script-leak.js b/test/es-module/test-vm-contextified-script-leak.js index a8625fc94d24..f44e4331ffc7 100644 --- a/test/es-module/test-vm-contextified-script-leak.js +++ b/test/es-module/test-vm-contextified-script-leak.js @@ -1,4 +1,4 @@ -// Flags: --max-old-space-size=16 --trace-gc +// Flags: --enable-async-hooks --max-old-space-size=16 --trace-gc 'use strict'; // This tests that vm.Script with dynamic import callback does not leak. diff --git a/test/es-module/test-vm-source-text-module-leak.js b/test/es-module/test-vm-source-text-module-leak.js index ad85c08e3937..e73abca7ff65 100644 --- a/test/es-module/test-vm-source-text-module-leak.js +++ b/test/es-module/test-vm-source-text-module-leak.js @@ -1,4 +1,4 @@ -// Flags: --experimental-vm-modules --max-old-space-size=16 --trace-gc +// Flags: --enable-async-hooks --experimental-vm-modules --max-old-space-size=16 --trace-gc 'use strict'; // This tests that vm.SourceTextModule() does not leak. diff --git a/test/es-module/test-vm-synthetic-module-leak.js b/test/es-module/test-vm-synthetic-module-leak.js index bc0e46895353..dd93898a6b2d 100644 --- a/test/es-module/test-vm-synthetic-module-leak.js +++ b/test/es-module/test-vm-synthetic-module-leak.js @@ -1,4 +1,4 @@ -// Flags: --experimental-vm-modules --max-old-space-size=16 +// Flags: --enable-async-hooks --experimental-vm-modules --max-old-space-size=16 'use strict'; // This tests that vm.SyntheticModule does not leak. diff --git a/test/node-api/test_async/test-async-hooks.js b/test/node-api/test_async/test-async-hooks.js index 956d210f3f08..775f5566183b 100644 --- a/test/node-api/test_async/test-async-hooks.js +++ b/test/node-api/test_async/test-async-hooks.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/node-api/test_async_context/test-gcable-callback.js b/test/node-api/test_async_context/test-gcable-callback.js index b1e4d29c5f41..6b3baccd119b 100644 --- a/test/node-api/test_async_context/test-gcable-callback.js +++ b/test/node-api/test_async_context/test-gcable-callback.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --gc-interval=100 --gc-global +// Flags: --enable-async-hooks --gc-interval=100 --gc-global const common = require('../../common'); const assert = require('assert'); diff --git a/test/node-api/test_async_context/test.js b/test/node-api/test_async_context/test.js index e4e46afbf2eb..2cb9fa246d6d 100644 --- a/test/node-api/test_async_context/test.js +++ b/test/node-api/test_async_context/test.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --gc-interval=100 --gc-global +// Flags: --enable-async-hooks --gc-interval=100 --gc-global const common = require('../../common'); const assert = require('assert'); diff --git a/test/node-api/test_callback_scope/test-async-hooks.js b/test/node-api/test_callback_scope/test-async-hooks.js index 7c12e25848d0..4a87660749c9 100644 --- a/test/node-api/test_callback_scope/test-async-hooks.js +++ b/test/node-api/test_callback_scope/test-async-hooks.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../../common'); const assert = require('assert'); diff --git a/test/node-api/test_make_callback/test-async-hooks.js b/test/node-api/test_make_callback/test-async-hooks.js index d6053c5058a1..610946d93b61 100644 --- a/test/node-api/test_make_callback/test-async-hooks.js +++ b/test/node-api/test_make_callback/test-async-hooks.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../../common'); const assert = require('assert'); diff --git a/test/parallel/test-async-hooks-async-await.js b/test/parallel/test-async-hooks-async-await.js index 97b50f3f2685..c8b8fa7ed9f8 100644 --- a/test/parallel/test-async-hooks-async-await.js +++ b/test/parallel/test-async-hooks-async-await.js @@ -1,6 +1,7 @@ // Test async-hooks fired on right // asyncIds & triggerAsyncId for async-await 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-asyncresource-constructor.js b/test/parallel/test-async-hooks-asyncresource-constructor.js index 8b504aa7a79e..39fb89205197 100644 --- a/test/parallel/test-async-hooks-asyncresource-constructor.js +++ b/test/parallel/test-async-hooks-asyncresource-constructor.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks // This tests that AsyncResource throws an error if bad parameters are passed diff --git a/test/parallel/test-async-hooks-close-during-destroy.js b/test/parallel/test-async-hooks-close-during-destroy.js index 6e485d2d1110..8cfa096ea4f5 100644 --- a/test/parallel/test-async-hooks-close-during-destroy.js +++ b/test/parallel/test-async-hooks-close-during-destroy.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks // Test that async ids that are added to the destroy queue while running a // `destroy` callback are handled correctly. diff --git a/test/parallel/test-async-hooks-constructor.js b/test/parallel/test-async-hooks-constructor.js index 62ec854108e9..9559c86c46ac 100644 --- a/test/parallel/test-async-hooks-constructor.js +++ b/test/parallel/test-async-hooks-constructor.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks // This tests that AsyncHooks throws an error if bad parameters are passed. diff --git a/test/parallel/test-async-hooks-correctly-switch-promise-hook.js b/test/parallel/test-async-hooks-correctly-switch-promise-hook.js index 73127f1ebaf9..1de9ed824fa2 100644 --- a/test/parallel/test-async-hooks-correctly-switch-promise-hook.js +++ b/test/parallel/test-async-hooks-correctly-switch-promise-hook.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-create-hook-disabled-internals.js b/test/parallel/test-async-hooks-create-hook-disabled-internals.js new file mode 100644 index 000000000000..70c4ff1c7e95 --- /dev/null +++ b/test/parallel/test-async-hooks-create-hook-disabled-internals.js @@ -0,0 +1,38 @@ +'use strict'; + +// Internals that use async_hooks for a purpose other than observing +// async_hooks themselves (e.g. node:test via AsyncLocalStorage) must keep +// working without --enable-async-hooks. Consumers that are themselves +// async_hooks observers (e.g. the `node.async_hooks` trace event category) +// require the flag. + +const common = require('../common'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); +const test = require('node:test'); + +test('node:test runs without --enable-async-hooks', common.mustCall()); + +{ + const tmpdir = require('../common/tmpdir'); + tmpdir.refresh(); + + // The `node.async_hooks` trace event category is itself an async_hooks + // consumer, so it requires --enable-async-hooks. + const child = spawnSync(process.execPath, [ + '--enable-async-hooks', + '--trace-event-categories', 'node.async_hooks', + '-e', 'setTimeout(() => {}, 1)', + ], { cwd: tmpdir.path, encoding: 'utf8' }); + assert.strictEqual(child.stderr, ''); + assert.strictEqual(child.status, 0); + + // Without --enable-async-hooks the same category must fail. + const childWithoutFlag = spawnSync(process.execPath, [ + '--trace-event-categories', 'node.async_hooks', + '-e', 'setTimeout(() => {}, 1)', + ], { cwd: tmpdir.path, encoding: 'utf8' }); + assert.notStrictEqual(childWithoutFlag.status, 0); + assert.match(childWithoutFlag.stderr, + /ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED/); +} diff --git a/test/parallel/test-async-hooks-create-hook-disabled.js b/test/parallel/test-async-hooks-create-hook-disabled.js new file mode 100644 index 000000000000..ad102c718f91 --- /dev/null +++ b/test/parallel/test-async-hooks-create-hook-disabled.js @@ -0,0 +1,15 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { createHook } = require('async_hooks'); + +// async_hooks.createHook is disabled by default (without --enable-async-hooks) +{ + assert.throws(() => { + createHook({ init() {} }); + }, common.expectsError({ + code: 'ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED', + message: 'async_hooks.createHook() is disabled. Use --enable-async-hooks to enable it.', + })); +} diff --git a/test/parallel/test-async-hooks-create-hook-enabled.js b/test/parallel/test-async-hooks-create-hook-enabled.js new file mode 100644 index 000000000000..4b6db49ac678 --- /dev/null +++ b/test/parallel/test-async-hooks-create-hook-enabled.js @@ -0,0 +1,18 @@ +// Flags: --enable-async-hooks +'use strict'; + +require('../common'); +const { createHook } = require('async_hooks'); + +// When --enable-async-hooks is passed, createHook should work +{ + // doesNotThrow + const hook = createHook({ + init() {}, + before() {}, + after() {}, + destroy() {}, + }); + hook.enable(); + hook.disable(); +} diff --git a/test/parallel/test-async-hooks-destroy-on-gc.js b/test/parallel/test-async-hooks-destroy-on-gc.js index a401f6651ccc..39558640f780 100644 --- a/test/parallel/test-async-hooks-destroy-on-gc.js +++ b/test/parallel/test-async-hooks-destroy-on-gc.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose_gc +// Flags: --enable-async-hooks --expose_gc // This test ensures that userland-only AsyncResources cause a destroy event to // be emitted when they get gced. diff --git a/test/parallel/test-async-hooks-disable-during-promise.js b/test/parallel/test-async-hooks-disable-during-promise.js index a25dae51e1f8..b63e735bec9d 100644 --- a/test/parallel/test-async-hooks-disable-during-promise.js +++ b/test/parallel/test-async-hooks-disable-during-promise.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const async_hooks = require('async_hooks'); const { isMainThread } = require('worker_threads'); diff --git a/test/parallel/test-async-hooks-disable-gc-tracking.js b/test/parallel/test-async-hooks-disable-gc-tracking.js index 87b096c25812..d227853a437d 100644 --- a/test/parallel/test-async-hooks-disable-gc-tracking.js +++ b/test/parallel/test-async-hooks-disable-gc-tracking.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose_gc +// Flags: --enable-async-hooks --expose_gc // This test ensures that userland-only AsyncResources cause a destroy event to // be emitted when they get gced. diff --git a/test/parallel/test-async-hooks-enable-before-promise-resolve.js b/test/parallel/test-async-hooks-enable-before-promise-resolve.js index e6facfb6392e..e9e8947dec09 100644 --- a/test/parallel/test-async-hooks-enable-before-promise-resolve.js +++ b/test/parallel/test-async-hooks-enable-before-promise-resolve.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-enable-disable-enable.js b/test/parallel/test-async-hooks-enable-disable-enable.js index 640815e14c8c..cc9a29f1206c 100644 --- a/test/parallel/test-async-hooks-enable-disable-enable.js +++ b/test/parallel/test-async-hooks-enable-disable-enable.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-enable-disable.js b/test/parallel/test-async-hooks-enable-disable.js index 71d35c91371f..4e6a1488bb10 100644 --- a/test/parallel/test-async-hooks-enable-disable.js +++ b/test/parallel/test-async-hooks-enable-disable.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-enable-during-promise.js b/test/parallel/test-async-hooks-enable-during-promise.js index ce3253b01c12..d861d6041bca 100644 --- a/test/parallel/test-async-hooks-enable-during-promise.js +++ b/test/parallel/test-async-hooks-enable-during-promise.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-enable-recursive.js b/test/parallel/test-async-hooks-enable-recursive.js index 74caebbad225..e04eb5385119 100644 --- a/test/parallel/test-async-hooks-enable-recursive.js +++ b/test/parallel/test-async-hooks-enable-recursive.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-enabledhooksexits.js b/test/parallel/test-async-hooks-enabledhooksexits.js index 11737d65485b..2aae942ab5ab 100644 --- a/test/parallel/test-async-hooks-enabledhooksexits.js +++ b/test/parallel/test-async-hooks-enabledhooksexits.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; require('../common'); diff --git a/test/parallel/test-async-hooks-execution-async-resource-await.js b/test/parallel/test-async-hooks-execution-async-resource-await.js index 8dc04c83d731..4a2a942f1635 100644 --- a/test/parallel/test-async-hooks-execution-async-resource-await.js +++ b/test/parallel/test-async-hooks-execution-async-resource-await.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const sleep = require('util').promisify(setTimeout); diff --git a/test/parallel/test-async-hooks-execution-async-resource.js b/test/parallel/test-async-hooks-execution-async-resource.js index b3a9f76ef4ec..0374548b7c80 100644 --- a/test/parallel/test-async-hooks-execution-async-resource.js +++ b/test/parallel/test-async-hooks-execution-async-resource.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/parallel/test-async-hooks-fatal-error.js b/test/parallel/test-async-hooks-fatal-error.js index 30ead86132f6..9447fc75f3b6 100644 --- a/test/parallel/test-async-hooks-fatal-error.js +++ b/test/parallel/test-async-hooks-fatal-error.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const childProcess = require('child_process'); @@ -41,7 +42,7 @@ function main() { for (const [valueType, expect] of valueTypes) { const cp = childProcess.spawnSync( process.execPath, - [ __filename, 'child', type, valueType ], + [ '--enable-async-hooks', __filename, 'child', type, valueType ], { encoding: 'utf8', }); diff --git a/test/parallel/test-async-hooks-http-agent-destroy.js b/test/parallel/test-async-hooks-http-agent-destroy.js index 4d90cb7d3507..12435fa3a1f9 100644 --- a/test/parallel/test-async-hooks-http-agent-destroy.js +++ b/test/parallel/test-async-hooks-http-agent-destroy.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals const common = require('../common'); const assert = require('assert'); const { async_id_symbol } = require('internal/async_hooks').symbols; diff --git a/test/parallel/test-async-hooks-http-agent.js b/test/parallel/test-async-hooks-http-agent.js index 337bab65d9df..9ff12a20a6e8 100644 --- a/test/parallel/test-async-hooks-http-agent.js +++ b/test/parallel/test-async-hooks-http-agent.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals const common = require('../common'); const assert = require('assert'); const { async_id_symbol } = require('internal/async_hooks').symbols; diff --git a/test/parallel/test-async-hooks-http-parser-destroy.js b/test/parallel/test-async-hooks-http-parser-destroy.js index b2d1fd9a94f1..d773ea1159f7 100644 --- a/test/parallel/test-async-hooks-http-parser-destroy.js +++ b/test/parallel/test-async-hooks-http-parser-destroy.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-prevent-double-destroy.js b/test/parallel/test-async-hooks-prevent-double-destroy.js index 4aa55a5a6c87..9b136cfcc2a3 100644 --- a/test/parallel/test-async-hooks-prevent-double-destroy.js +++ b/test/parallel/test-async-hooks-prevent-double-destroy.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose_gc +// Flags: --enable-async-hooks --expose_gc // This test ensures that userland-only AsyncResources cause a destroy event to // be emitted when they get gced. diff --git a/test/parallel/test-async-hooks-promise-enable-disable.js b/test/parallel/test-async-hooks-promise-enable-disable.js index 92504ac121e5..6e1e9135555f 100644 --- a/test/parallel/test-async-hooks-promise-enable-disable.js +++ b/test/parallel/test-async-hooks-promise-enable-disable.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/parallel/test-async-hooks-promise-triggerid.js b/test/parallel/test-async-hooks-promise-triggerid.js index 89e5bc1464f8..7193223b4755 100644 --- a/test/parallel/test-async-hooks-promise-triggerid.js +++ b/test/parallel/test-async-hooks-promise-triggerid.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-promise.js b/test/parallel/test-async-hooks-promise.js index 74f72a188240..d05bef69e9ea 100644 --- a/test/parallel/test-async-hooks-promise.js +++ b/test/parallel/test-async-hooks-promise.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-recursive-stack-runInAsyncScope.js b/test/parallel/test-async-hooks-recursive-stack-runInAsyncScope.js index d0d5ee76e9d1..b71927724c9d 100644 --- a/test/parallel/test-async-hooks-recursive-stack-runInAsyncScope.js +++ b/test/parallel/test-async-hooks-recursive-stack-runInAsyncScope.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-run-in-async-scope-caught-exception.js b/test/parallel/test-async-hooks-run-in-async-scope-caught-exception.js index e38cefd20e4f..28108543b568 100644 --- a/test/parallel/test-async-hooks-run-in-async-scope-caught-exception.js +++ b/test/parallel/test-async-hooks-run-in-async-scope-caught-exception.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks require('../common'); const { AsyncResource } = require('async_hooks'); diff --git a/test/parallel/test-async-hooks-run-in-async-scope-this-arg.js b/test/parallel/test-async-hooks-run-in-async-scope-this-arg.js index a5016da9d5fc..a59b4595f420 100644 --- a/test/parallel/test-async-hooks-run-in-async-scope-this-arg.js +++ b/test/parallel/test-async-hooks-run-in-async-scope-this-arg.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks // Test that passing thisArg to runInAsyncScope() works. diff --git a/test/parallel/test-async-hooks-stack-overflow-nested-async.js b/test/parallel/test-async-hooks-stack-overflow-nested-async.js index 779f8d75ae20..c6ba3c7e977e 100644 --- a/test/parallel/test-async-hooks-stack-overflow-nested-async.js +++ b/test/parallel/test-async-hooks-stack-overflow-nested-async.js @@ -66,7 +66,7 @@ if (process.argv[2] === 'child') { // Parent process - spawn the child and check exit code const result = spawnSync( process.execPath, - [__filename, 'child'], + ['--enable-async-hooks', __filename, 'child'], { encoding: 'utf8', timeout: 30000 } ); diff --git a/test/parallel/test-async-hooks-stack-overflow-try-catch.js b/test/parallel/test-async-hooks-stack-overflow-try-catch.js index 43338905e78b..f25dcbb9fd1c 100644 --- a/test/parallel/test-async-hooks-stack-overflow-try-catch.js +++ b/test/parallel/test-async-hooks-stack-overflow-try-catch.js @@ -35,7 +35,7 @@ if (process.argv[2] === 'child') { // Parent process - spawn the child and check exit code const result = spawnSync( process.execPath, - [__filename, 'child'], + ['--enable-async-hooks', __filename, 'child'], { encoding: 'utf8', timeout: 30000 } ); diff --git a/test/parallel/test-async-hooks-stack-overflow.js b/test/parallel/test-async-hooks-stack-overflow.js index aff41969dbdf..ea00b07c2414 100644 --- a/test/parallel/test-async-hooks-stack-overflow.js +++ b/test/parallel/test-async-hooks-stack-overflow.js @@ -34,7 +34,7 @@ if (process.argv[2] === 'child') { // Parent process - spawn the child and check exit code const result = spawnSync( process.execPath, - [__filename, 'child'], + ['--enable-async-hooks', __filename, 'child'], { encoding: 'utf8', timeout: 30000 } ); diff --git a/test/parallel/test-async-hooks-top-level-clearimmediate.js b/test/parallel/test-async-hooks-top-level-clearimmediate.js index fd91fefa9c4b..b966560ba6f5 100644 --- a/test/parallel/test-async-hooks-top-level-clearimmediate.js +++ b/test/parallel/test-async-hooks-top-level-clearimmediate.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks // Regression test for https://github.com/nodejs/node/issues/13262 diff --git a/test/parallel/test-async-hooks-vm-gc.js b/test/parallel/test-async-hooks-vm-gc.js index da95e3579dcc..cef7b4ed2690 100644 --- a/test/parallel/test-async-hooks-vm-gc.js +++ b/test/parallel/test-async-hooks-vm-gc.js @@ -1,4 +1,4 @@ -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc 'use strict'; require('../common'); diff --git a/test/parallel/test-async-hooks-worker-asyncfn-terminate-1.js b/test/parallel/test-async-hooks-worker-asyncfn-terminate-1.js index eb1664591308..fcb1dad52621 100644 --- a/test/parallel/test-async-hooks-worker-asyncfn-terminate-1.js +++ b/test/parallel/test-async-hooks-worker-asyncfn-terminate-1.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const { Worker } = require('worker_threads'); diff --git a/test/parallel/test-async-hooks-worker-asyncfn-terminate-2.js b/test/parallel/test-async-hooks-worker-asyncfn-terminate-2.js index 049264d3e8ae..75f00029caf4 100644 --- a/test/parallel/test-async-hooks-worker-asyncfn-terminate-2.js +++ b/test/parallel/test-async-hooks-worker-asyncfn-terminate-2.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const { Worker } = require('worker_threads'); diff --git a/test/parallel/test-async-hooks-worker-asyncfn-terminate-3.js b/test/parallel/test-async-hooks-worker-asyncfn-terminate-3.js index 40c7d85835ae..1dc2cc5ba08d 100644 --- a/test/parallel/test-async-hooks-worker-asyncfn-terminate-3.js +++ b/test/parallel/test-async-hooks-worker-asyncfn-terminate-3.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const { Worker } = require('worker_threads'); diff --git a/test/parallel/test-async-hooks-worker-asyncfn-terminate-4.js b/test/parallel/test-async-hooks-worker-asyncfn-terminate-4.js index c522091006cf..b6136ac9cc75 100644 --- a/test/parallel/test-async-hooks-worker-asyncfn-terminate-4.js +++ b/test/parallel/test-async-hooks-worker-asyncfn-terminate-4.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const { Worker } = require('worker_threads'); diff --git a/test/parallel/test-async-local-storage-http-parser-leak.js b/test/parallel/test-async-local-storage-http-parser-leak.js index b55aed8717ab..2d8f3e5a9d67 100644 --- a/test/parallel/test-async-local-storage-http-parser-leak.js +++ b/test/parallel/test-async-local-storage-http-parser-leak.js @@ -1,4 +1,4 @@ -// Flags: --expose-gc --expose-internals +// Flags: --enable-async-hooks --expose-gc --expose-internals 'use strict'; diff --git a/test/parallel/test-async-wrap-constructor.js b/test/parallel/test-async-wrap-constructor.js index 853898aa0adf..8ef02e936996 100644 --- a/test/parallel/test-async-wrap-constructor.js +++ b/test/parallel/test-async-wrap-constructor.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks // This tests that using falsy values in createHook throws an error. diff --git a/test/parallel/test-async-wrap-destroyid.js b/test/parallel/test-async-wrap-destroyid.js index 25a33246e775..6a1f2e262279 100644 --- a/test/parallel/test-async-wrap-destroyid.js +++ b/test/parallel/test-async-wrap-destroyid.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; const common = require('../common'); diff --git a/test/parallel/test-async-wrap-pop-id-during-load.js b/test/parallel/test-async-wrap-pop-id-during-load.js index bd53c4d7893d..c2c27c2cc542 100644 --- a/test/parallel/test-async-wrap-pop-id-during-load.js +++ b/test/parallel/test-async-wrap-pop-id-during-load.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks require('../common'); diff --git a/test/parallel/test-async-wrap-promise-after-enabled.js b/test/parallel/test-async-wrap-promise-after-enabled.js index fafb732c2895..bfe2b0ca8587 100644 --- a/test/parallel/test-async-wrap-promise-after-enabled.js +++ b/test/parallel/test-async-wrap-promise-after-enabled.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks // Regression test for https://github.com/nodejs/node/issues/13237 diff --git a/test/parallel/test-async-wrap-tlssocket-asyncreset.js b/test/parallel/test-async-wrap-tlssocket-asyncreset.js index 513911978b1d..b6b300453bbc 100644 --- a/test/parallel/test-async-wrap-tlssocket-asyncreset.js +++ b/test/parallel/test-async-wrap-tlssocket-asyncreset.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); const fixtures = require('../common/fixtures'); diff --git a/test/parallel/test-async-wrap-trigger-id.js b/test/parallel/test-async-wrap-trigger-id.js index e8b4682b7167..2b6455be98ae 100644 --- a/test/parallel/test-async-wrap-trigger-id.js +++ b/test/parallel/test-async-wrap-trigger-id.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks require('../common'); const assert = require('assert'); diff --git a/test/parallel/test-async-wrap-uncaughtexception.js b/test/parallel/test-async-wrap-uncaughtexception.js index 37557b4aacc3..6afa94bff802 100644 --- a/test/parallel/test-async-wrap-uncaughtexception.js +++ b/test/parallel/test-async-wrap-uncaughtexception.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasCrypto) diff --git a/test/parallel/test-cli-node-options.js b/test/parallel/test-cli-node-options.js index fa290d23c961..ec7680e4eff6 100644 --- a/test/parallel/test-cli-node-options.js +++ b/test/parallel/test-cli-node-options.js @@ -33,7 +33,7 @@ expect('--no-extra-info-on-fatal-exception', 'B\n'); expect('--redirect-warnings=_', 'B\n'); expect('--trace-deprecation', 'B\n'); expect('--trace-sync-io', 'B\n'); -expectNoWorker('--trace-events-enabled', 'B\n'); +expectNoWorker('--trace-events-enabled --enable-async-hooks', 'B\n'); expect('--track-heap-objects', 'B\n'); expect('--throw-deprecation', /.*DeprecationWarning: Buffer\(\) is deprecated due to security and usability issues.*/, @@ -49,7 +49,7 @@ expectNoWorker( ); // eslint-disable-next-line no-template-curly-in-string expectNoWorker('--trace-event-file-pattern {pid}-${rotation}.trace_events ' + - '--trace-event-categories node.async_hooks', 'B\n'); + '--trace-event-categories node.async_hooks --enable-async-hooks', 'B\n'); expect('--unhandled-rejections=none', 'B\n'); if (common.isLinux) { diff --git a/test/parallel/test-common-gc.js b/test/parallel/test-common-gc.js index 54abe3695cc3..c205ee89f9cc 100644 --- a/test/parallel/test-common-gc.js +++ b/test/parallel/test-common-gc.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc const common = require('../common'); const { onGC } = require('../common/gc'); diff --git a/test/parallel/test-diagnostics-channel-memory-leak.js b/test/parallel/test-diagnostics-channel-memory-leak.js index 06301847ed6b..c0f6f8d812c5 100644 --- a/test/parallel/test-diagnostics-channel-memory-leak.js +++ b/test/parallel/test-diagnostics-channel-memory-leak.js @@ -1,4 +1,4 @@ -// Flags: --max-old-space-size=16 +// Flags: --enable-async-hooks --max-old-space-size=16 'use strict'; // This test ensures that diagnostic channel references aren't leaked. diff --git a/test/parallel/test-emit-after-uncaught-exception.js b/test/parallel/test-emit-after-uncaught-exception.js index 5003972e9984..6eb47fcd87e0 100644 --- a/test/parallel/test-emit-after-uncaught-exception.js +++ b/test/parallel/test-emit-after-uncaught-exception.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); diff --git a/test/parallel/test-eventemitter-asyncresource.js b/test/parallel/test-eventemitter-asyncresource.js index fe7839a1bb23..4de57d09fc31 100644 --- a/test/parallel/test-eventemitter-asyncresource.js +++ b/test/parallel/test-eventemitter-asyncresource.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const { EventEmitterAsyncResource } = require('events'); diff --git a/test/parallel/test-fs-cp-async-destination-appears-late.mjs b/test/parallel/test-fs-cp-async-destination-appears-late.mjs index 40ec15e1ef39..dd777678bdb2 100644 --- a/test/parallel/test-fs-cp-async-destination-appears-late.mjs +++ b/test/parallel/test-fs-cp-async-destination-appears-late.mjs @@ -1,3 +1,4 @@ +// Flags: --enable-async-hooks // This tests that cp() into a destination that did not exist when it was // checked, but does by the time the copy starts, fails with EEXIST instead // of copying through whatever appeared there. diff --git a/test/parallel/test-fs-existssync-memleak-longpath.js b/test/parallel/test-fs-existssync-memleak-longpath.js index 90617badc96d..ebfe395c4f16 100644 --- a/test/parallel/test-fs-existssync-memleak-longpath.js +++ b/test/parallel/test-fs-existssync-memleak-longpath.js @@ -1,4 +1,4 @@ -// Flags: --expose-gc --expose-internals +// Flags: --enable-async-hooks --expose-gc --expose-internals 'use strict'; const common = require('../common'); diff --git a/test/parallel/test-fs-readfile-one-roundtrip.js b/test/parallel/test-fs-readfile-one-roundtrip.js index 87df04795d8d..a0d423426a80 100644 --- a/test/parallel/test-fs-readfile-one-roundtrip.js +++ b/test/parallel/test-fs-readfile-one-roundtrip.js @@ -1,3 +1,4 @@ +// Flags: --enable-async-hooks 'use strict'; // fs.readFile()/fs.promises.readFile() read files of up to one chunk // (512 KiB) with a single thread pool round trip and hand larger files over diff --git a/test/parallel/test-gc-http-client-connaborted.js b/test/parallel/test-gc-http-client-connaborted.js index e52a555d7880..3ce541f26842 100644 --- a/test/parallel/test-gc-http-client-connaborted.js +++ b/test/parallel/test-gc-http-client-connaborted.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc // just like test-gc-http-client.js, // but aborting every connection that comes in. diff --git a/test/parallel/test-gc-net-timeout.js b/test/parallel/test-gc-net-timeout.js index 0fc93bfc62c2..d621b39ce362 100644 --- a/test/parallel/test-gc-net-timeout.js +++ b/test/parallel/test-gc-net-timeout.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc // just like test-gc-http-client-timeout.js, // but using a net server/client instead diff --git a/test/parallel/test-gc-tls-external-memory.js b/test/parallel/test-gc-tls-external-memory.js index 480b1086b539..d4bb4c0c7a68 100644 --- a/test/parallel/test-gc-tls-external-memory.js +++ b/test/parallel/test-gc-tls-external-memory.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc // Tests that memoryUsage().external doesn't go negative // when a lot tls connections are opened and closed diff --git a/test/parallel/test-heapdump-async-hooks-init-promise.js b/test/parallel/test-heapdump-async-hooks-init-promise.js index 80d6309deabd..086d5bc1a789 100644 --- a/test/parallel/test-heapdump-async-hooks-init-promise.js +++ b/test/parallel/test-heapdump-async-hooks-init-promise.js @@ -1,4 +1,4 @@ -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc 'use strict'; const common = require('../common'); const assert = require('assert'); diff --git a/test/parallel/test-http-agent-domain-reused-gc.js b/test/parallel/test-http-agent-domain-reused-gc.js index 4f12c2ede839..abad3d8f16df 100644 --- a/test/parallel/test-http-agent-domain-reused-gc.js +++ b/test/parallel/test-http-agent-domain-reused-gc.js @@ -1,4 +1,4 @@ -// Flags: --expose-gc --expose-internals +// Flags: --enable-async-hooks --expose-gc --expose-internals 'use strict'; const common = require('../common'); const http = require('http'); diff --git a/test/parallel/test-http-client-leaky-with-double-response.js b/test/parallel/test-http-client-leaky-with-double-response.js index a569b3bb31be..03ba6abe8f74 100644 --- a/test/parallel/test-http-client-leaky-with-double-response.js +++ b/test/parallel/test-http-client-leaky-with-double-response.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc const common = require('../common'); const http = require('http'); const assert = require('assert'); diff --git a/test/parallel/test-http-server-connections-checking-leak.js b/test/parallel/test-http-server-connections-checking-leak.js index 38dca83102cf..4070d1a17bcb 100644 --- a/test/parallel/test-http-server-connections-checking-leak.js +++ b/test/parallel/test-http-server-connections-checking-leak.js @@ -1,6 +1,6 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc // Check that creating a server without listening does not leak resources. diff --git a/test/parallel/test-http-server-keepalive-req-gc.js b/test/parallel/test-http-server-keepalive-req-gc.js index c827cd19ad72..8850a800e873 100644 --- a/test/parallel/test-http-server-keepalive-req-gc.js +++ b/test/parallel/test-http-server-keepalive-req-gc.js @@ -1,4 +1,4 @@ -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc 'use strict'; const common = require('../common'); const { onGC } = require('../common/gc'); diff --git a/test/parallel/test-http-uncaught-from-request-callback.js b/test/parallel/test-http-uncaught-from-request-callback.js index 5c7595861789..86f5b2a73eaf 100644 --- a/test/parallel/test-http-uncaught-from-request-callback.js +++ b/test/parallel/test-http-uncaught-from-request-callback.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const asyncHooks = require('async_hooks'); const http = require('http'); diff --git a/test/parallel/test-http2-debug.js b/test/parallel/test-http2-debug.js index c7252317be3a..49a7f1468b1f 100644 --- a/test/parallel/test-http2-debug.js +++ b/test/parallel/test-http2-debug.js @@ -15,6 +15,7 @@ const stderrFile = tmpdir.resolve('stderr.log'); const stderrFd = fs.openSync(stderrFile, 'w'); try { spawnSyncAndAssert(process.execPath, [ + '--enable-async-hooks', path.resolve(__dirname, 'test-http2-ping.js'), ], { env: { diff --git a/test/parallel/test-http2-ping.js b/test/parallel/test-http2-ping.js index 90ef57e03ccf..0d0958f88b72 100644 --- a/test/parallel/test-http2-ping.js +++ b/test/parallel/test-http2-ping.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); if (!common.hasCrypto) diff --git a/test/parallel/test-https-server-connections-checking-leak.js b/test/parallel/test-https-server-connections-checking-leak.js index f79149ef70a9..b9d3dbc2e497 100644 --- a/test/parallel/test-https-server-connections-checking-leak.js +++ b/test/parallel/test-https-server-connections-checking-leak.js @@ -1,6 +1,6 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc // Check that creating a server without listening does not leak resources. diff --git a/test/parallel/test-inspector-contexts.js b/test/parallel/test-inspector-contexts.js index 9ab2c515b4a9..39749dfcca38 100644 --- a/test/parallel/test-inspector-contexts.js +++ b/test/parallel/test-inspector-contexts.js @@ -1,6 +1,6 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc const common = require('../common'); common.skipIfInspectorDisabled(); diff --git a/test/parallel/test-inspector-debug-async-hook.js b/test/parallel/test-inspector-debug-async-hook.js index e8f13b40c7e4..fa2bb5f71432 100644 --- a/test/parallel/test-inspector-debug-async-hook.js +++ b/test/parallel/test-inspector-debug-async-hook.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); common.skipIfInspectorDisabled(); const test = require('node:test'); diff --git a/test/parallel/test-internal-util-weakreference.js b/test/parallel/test-internal-util-weakreference.js index 0ecef956a44a..d98839093c76 100644 --- a/test/parallel/test-internal-util-weakreference.js +++ b/test/parallel/test-internal-util-weakreference.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals --expose-gc +// Flags: --enable-async-hooks --expose-internals --expose-gc 'use strict'; require('../common'); const { gcUntil } = require('../common/gc'); diff --git a/test/parallel/test-messageport-hasref.js b/test/parallel/test-messageport-hasref.js index 563a598b3658..b2a810acbec9 100644 --- a/test/parallel/test-messageport-hasref.js +++ b/test/parallel/test-messageport-hasref.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const { MessageChannel } = require('worker_threads'); diff --git a/test/parallel/test-net-connect-memleak.js b/test/parallel/test-net-connect-memleak.js index de925f5d08c4..e329722c2b78 100644 --- a/test/parallel/test-net-connect-memleak.js +++ b/test/parallel/test-net-connect-memleak.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc const common = require('../common'); const { onGC } = require('../common/gc'); diff --git a/test/parallel/test-primitive-timer-leak.js b/test/parallel/test-primitive-timer-leak.js index a0fe2765e128..a231012b328d 100644 --- a/test/parallel/test-primitive-timer-leak.js +++ b/test/parallel/test-primitive-timer-leak.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc require('../common'); const { onGC } = require('../common/gc'); diff --git a/test/parallel/test-promise-hook-create-hook.js b/test/parallel/test-promise-hook-create-hook.js index 543f67da4860..95820419ef42 100644 --- a/test/parallel/test-promise-hook-create-hook.js +++ b/test/parallel/test-promise-hook-create-hook.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const { promiseHooks } = require('v8'); diff --git a/test/parallel/test-queue-microtask-uncaught-asynchooks.js b/test/parallel/test-queue-microtask-uncaught-asynchooks.js index 35b3d9fa309a..f2f39707023e 100644 --- a/test/parallel/test-queue-microtask-uncaught-asynchooks.js +++ b/test/parallel/test-queue-microtask-uncaught-asynchooks.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); diff --git a/test/parallel/test-shadow-realm-gc-module.js b/test/parallel/test-shadow-realm-gc-module.js index 6077bf03146d..c0109f495c13 100644 --- a/test/parallel/test-shadow-realm-gc-module.js +++ b/test/parallel/test-shadow-realm-gc-module.js @@ -1,4 +1,4 @@ -// Flags: --experimental-shadow-realm --max-old-space-size=20 +// Flags: --enable-async-hooks --experimental-shadow-realm --max-old-space-size=20 'use strict'; /** diff --git a/test/parallel/test-shadow-realm-gc.js b/test/parallel/test-shadow-realm-gc.js index c6de4a32a88f..e1a0827256ee 100644 --- a/test/parallel/test-shadow-realm-gc.js +++ b/test/parallel/test-shadow-realm-gc.js @@ -1,4 +1,4 @@ -// Flags: --experimental-shadow-realm --max-old-space-size=20 +// Flags: --enable-async-hooks --experimental-shadow-realm --max-old-space-size=20 'use strict'; /** diff --git a/test/parallel/test-source-map-cjs-require-cache.js b/test/parallel/test-source-map-cjs-require-cache.js index 155b7a66efab..3639f64fd348 100644 --- a/test/parallel/test-source-map-cjs-require-cache.js +++ b/test/parallel/test-source-map-cjs-require-cache.js @@ -1,4 +1,4 @@ -// Flags: --enable-source-maps --max-old-space-size=10 --expose-gc +// Flags: --enable-async-hooks --enable-source-maps --max-old-space-size=10 --expose-gc /** * This test verifies that the source map of a CJS module is cleared after the diff --git a/test/parallel/test-sqlite-session.js b/test/parallel/test-sqlite-session.js index e5a478e17061..7ef87e3597ea 100644 --- a/test/parallel/test-sqlite-session.js +++ b/test/parallel/test-sqlite-session.js @@ -1,4 +1,4 @@ -// Flags: --expose-gc --experimental-sqlite +// Flags: --enable-async-hooks --expose-gc --experimental-sqlite 'use strict'; const { skipIfSQLiteMissing } = require('../common'); skipIfSQLiteMissing(); diff --git a/test/parallel/test-stream-finished-bindAsyncResource-path.js b/test/parallel/test-stream-finished-bindAsyncResource-path.js index 82de2947c29b..941f88d42713 100644 --- a/test/parallel/test-stream-finished-bindAsyncResource-path.js +++ b/test/parallel/test-stream-finished-bindAsyncResource-path.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; const common = require('../common'); diff --git a/test/parallel/test-stream-writable-samecb-singletick.js b/test/parallel/test-stream-writable-samecb-singletick.js index 9357a56535b6..ca5553e0dc9a 100644 --- a/test/parallel/test-stream-writable-samecb-singletick.js +++ b/test/parallel/test-stream-writable-samecb-singletick.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const { Console } = require('console'); const { Writable } = require('stream'); diff --git a/test/parallel/test-tls-connect-memleak.js b/test/parallel/test-tls-connect-memleak.js index 220ea4a9248e..90f2d6512ccb 100644 --- a/test/parallel/test-tls-connect-memleak.js +++ b/test/parallel/test-tls-connect-memleak.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc const common = require('../common'); if (!common.hasCrypto) diff --git a/test/parallel/test-trace-events-async-hooks-dynamic.js b/test/parallel/test-trace-events-async-hooks-dynamic.js index 8c6ef26e6387..0d56e2d2aa9b 100644 --- a/test/parallel/test-trace-events-async-hooks-dynamic.js +++ b/test/parallel/test-trace-events-async-hooks-dynamic.js @@ -29,7 +29,7 @@ const filename = tmpdir.resolve('node_trace.1.log'); tmpdir.refresh(); const proc = cp.spawnSync( process.execPath, - ['-e', enable + code ], + ['--enable-async-hooks', '-e', enable + code ], { cwd: tmpdir.path, env: { ...process.env, diff --git a/test/parallel/test-trace-events-perfetto-pftrace.js b/test/parallel/test-trace-events-perfetto-pftrace.js index 8cfcb52182df..63a3cf112635 100644 --- a/test/parallel/test-trace-events-perfetto-pftrace.js +++ b/test/parallel/test-trace-events-perfetto-pftrace.js @@ -17,7 +17,7 @@ tmpdir.refresh(); const FILE_NAME = tmpdir.resolve('node_trace.1.pftrace'); const proc = cp.spawn(process.execPath, - [ '--trace-events-enabled', '-e', CODE ], + [ '--enable-async-hooks', '--trace-events-enabled', '-e', CODE ], { cwd: tmpdir.path }); proc.once('exit', common.mustCall(() => { diff --git a/test/parallel/test-util-debounce.js b/test/parallel/test-util-debounce.js index 15d93e610418..04ff7ef6d586 100644 --- a/test/parallel/test-util-debounce.js +++ b/test/parallel/test-util-debounce.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; const common = require('../common'); diff --git a/test/parallel/test-util-throttle.js b/test/parallel/test-util-throttle.js index b22fb4630e7e..4d2fcaa901a0 100644 --- a/test/parallel/test-util-throttle.js +++ b/test/parallel/test-util-throttle.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals +// Flags: --enable-async-hooks --expose-internals 'use strict'; const common = require('../common'); diff --git a/test/parallel/test-v8-coverage.js b/test/parallel/test-v8-coverage.js index 0306e07c6fda..470c33878234 100644 --- a/test/parallel/test-v8-coverage.js +++ b/test/parallel/test-v8-coverage.js @@ -153,6 +153,7 @@ function nextdir() { { const coverageDirectory = tmpdir.resolve(nextdir()); const output = spawnSync(process.execPath, [ + '--enable-async-hooks', require.resolve('../fixtures/v8-coverage/async-hooks'), ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); if (output.status !== 0) { diff --git a/test/parallel/test-v8-serialize-leak.js b/test/parallel/test-v8-serialize-leak.js index dd51a879efff..af79c6fcea8a 100644 --- a/test/parallel/test-v8-serialize-leak.js +++ b/test/parallel/test-v8-serialize-leak.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc const common = require('../common'); const { gcUntil } = require('../common/gc'); diff --git a/test/parallel/test-worker-hasref.js b/test/parallel/test-worker-hasref.js index 936a144bebba..dbec73de150f 100644 --- a/test/parallel/test-worker-hasref.js +++ b/test/parallel/test-worker-hasref.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const { Worker } = require('worker_threads'); diff --git a/test/parallel/test-worker-message-port-inspect-during-init-hook.js b/test/parallel/test-worker-message-port-inspect-during-init-hook.js index d5784dceb71d..4bc29ac3e5ce 100644 --- a/test/parallel/test-worker-message-port-inspect-during-init-hook.js +++ b/test/parallel/test-worker-message-port-inspect-during-init-hook.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const util = require('util'); const assert = require('assert'); diff --git a/test/parallel/test-worker-messageport-hasref.js b/test/parallel/test-worker-messageport-hasref.js index c46feb7c66ee..7d301bbcf227 100644 --- a/test/parallel/test-worker-messageport-hasref.js +++ b/test/parallel/test-worker-messageport-hasref.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks const common = require('../common'); const { Worker } = require('worker_threads'); diff --git a/test/parallel/test-zlib-invalid-input-memory.js b/test/parallel/test-zlib-invalid-input-memory.js index ac718395dae1..dd15be0d6307 100644 --- a/test/parallel/test-zlib-invalid-input-memory.js +++ b/test/parallel/test-zlib-invalid-input-memory.js @@ -1,4 +1,4 @@ -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc 'use strict'; const common = require('../common'); const { onGC } = require('../common/gc'); diff --git a/test/pseudo-tty/test-async-wrap-getasyncid-tty.js b/test/pseudo-tty/test-async-wrap-getasyncid-tty.js index 5995a9118110..c984cb247e8d 100644 --- a/test/pseudo-tty/test-async-wrap-getasyncid-tty.js +++ b/test/pseudo-tty/test-async-wrap-getasyncid-tty.js @@ -1,4 +1,4 @@ -// Flags: --expose-internals --no-warnings +// Flags: --enable-async-hooks --expose-internals --no-warnings 'use strict'; // See also test/sequential/test-async-wrap-getasyncid.js diff --git a/test/sequential/test-async-wrap-getasyncid.js b/test/sequential/test-async-wrap-getasyncid.js index 2cb15e144ee9..0e3ea9147c0f 100644 --- a/test/sequential/test-async-wrap-getasyncid.js +++ b/test/sequential/test-async-wrap-getasyncid.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc --expose-internals --no-warnings --test-udp-no-try-send +// Flags: --enable-async-hooks --expose-gc --expose-internals --no-warnings --test-udp-no-try-send const common = require('../common'); const { internalBinding } = require('internal/test/binding'); diff --git a/test/sequential/test-gc-http-client-onerror.js b/test/sequential/test-gc-http-client-onerror.js index 1c311c6a9b64..1f5b8fc9b84a 100644 --- a/test/sequential/test-gc-http-client-onerror.js +++ b/test/sequential/test-gc-http-client-onerror.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc // just like test-gc-http-client.js, // but with an on('error') handler that does nothing. diff --git a/test/sequential/test-gc-http-client-timeout.js b/test/sequential/test-gc-http-client-timeout.js index bd5589fca109..b5d94bf6141f 100644 --- a/test/sequential/test-gc-http-client-timeout.js +++ b/test/sequential/test-gc-http-client-timeout.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc // Like test-gc-http-client.js, but with a timeout set. const common = require('../common'); diff --git a/test/sequential/test-gc-http-client.js b/test/sequential/test-gc-http-client.js index 6b2a5fc03afb..cd0de81c13b7 100644 --- a/test/sequential/test-gc-http-client.js +++ b/test/sequential/test-gc-http-client.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-gc +// Flags: --enable-async-hooks --expose-gc // just a simple http server and client. const common = require('../common'); diff --git a/test/trace_events/test-trace-events-all.js b/test/trace_events/test-trace-events-all.js index fe422d03a77a..00bedb68d998 100644 --- a/test/trace_events/test-trace-events-all.js +++ b/test/trace_events/test-trace-events-all.js @@ -21,7 +21,7 @@ tmpdir.refresh(); const FILE_NAME = tmpdir.resolve(defaultTraceFileName); const proc = cp.spawn(process.execPath, - [ '--trace-events-enabled', '-e', CODE ], + [ '--enable-async-hooks', '--trace-events-enabled', '-e', CODE ], { cwd: tmpdir.path }); proc.once('exit', common.mustCall(() => { diff --git a/test/trace_events/test-trace-events-async-hooks-worker.js b/test/trace_events/test-trace-events-async-hooks-worker.js index 4fdeb2138ebe..ddde1ea569f7 100644 --- a/test/trace_events/test-trace-events-async-hooks-worker.js +++ b/test/trace_events/test-trace-events-async-hooks-worker.js @@ -40,7 +40,7 @@ const filename = tmpdir.resolve(defaultTraceFileName); tmpdir.refresh(); const proc = cp.spawnSync( process.execPath, - [ '--trace-event-categories', 'node.async_hooks', '-e', worker ], + [ '--enable-async-hooks', '--trace-event-categories', 'node.async_hooks', '-e', worker ], { cwd: tmpdir.path, env: { ...process.env, diff --git a/test/trace_events/test-trace-events-async-hooks.js b/test/trace_events/test-trace-events-async-hooks.js index c404402594a1..b931bf39e2b3 100644 --- a/test/trace_events/test-trace-events-async-hooks.js +++ b/test/trace_events/test-trace-events-async-hooks.js @@ -22,7 +22,7 @@ tmpdir.refresh(); const FILE_NAME = tmpdir.resolve(defaultTraceFileName); const proc = cp.spawn(process.execPath, - [ '--trace-event-categories', 'node.async_hooks', + [ '--enable-async-hooks', '--trace-event-categories', 'node.async_hooks', '-e', CODE ], { cwd: tmpdir.path }); diff --git a/test/trace_events/test-trace-events-file-pattern.js b/test/trace_events/test-trace-events-file-pattern.js index 4b053aeb60cb..90bee8e2cc3c 100644 --- a/test/trace_events/test-trace-events-file-pattern.js +++ b/test/trace_events/test-trace-events-file-pattern.js @@ -18,6 +18,7 @@ const CODE = 'setTimeout(() => { for (let i = 0; i < 100000; i++) { "test" + i } }, 1)'; const proc = cp.spawn(process.execPath, [ + '--enable-async-hooks', '--trace-events-enabled', '--trace-event-file-pattern', // eslint-disable-next-line no-template-curly-in-string diff --git a/test/trace_events/test-trace-events-process-exit.js b/test/trace_events/test-trace-events-process-exit.js index cb09c1e3cdcc..e5946989eeaf 100644 --- a/test/trace_events/test-trace-events-process-exit.js +++ b/test/trace_events/test-trace-events-process-exit.js @@ -17,7 +17,7 @@ tmpdir.refresh(); const FILE_NAME = tmpdir.resolve(defaultTraceFileName); const proc = cp.spawn(process.execPath, - [ '--trace-events-enabled', + [ '--enable-async-hooks', '--trace-events-enabled', '-e', 'process.exit()' ], { cwd: tmpdir.path }); From 2b1db9df6c1d00ec1389054f6d156eab54c96ed3 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Fri, 30 Oct 2026 16:58:12 +0000 Subject: [PATCH 2/7] async_hooks: inline internal inspector async hook The internal AsyncHook class was added to internal/async_hooks solely so the inspector could create a hook without --enable-async-hooks, complete with ERR_ASYNC_CALLBACK validation that is not needed for an internal-only consumer. The inspector is the only internal consumer (the node.async_hooks trace event category intentionally still requires the flag), so register its hook directly from internal/inspector_async_hook instead. Since the inspector hook always registers init/before/after/destroy, the generic class and its validation add no value. Remove it and inline the minimal wiring. Refs: https://github.com/nodejs/node/pull/61030 Signed-off-by: Matteo Collina Assisted-by: pi --- lib/internal/async_hooks.js | 79 --------------------------- lib/internal/inspector_async_hook.js | 82 +++++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 87 deletions(-) diff --git a/lib/internal/async_hooks.js b/lib/internal/async_hooks.js index 01b232ac2a82..8a60b9a6ce52 100644 --- a/lib/internal/async_hooks.js +++ b/lib/internal/async_hooks.js @@ -1,11 +1,7 @@ 'use strict'; const { - ArrayPrototypeIncludes, - ArrayPrototypeIndexOf, - ArrayPrototypePush, ArrayPrototypeSlice, - ArrayPrototypeSplice, ErrorCaptureStackTrace, ObjectDefineProperty, ObjectPrototypeHasOwnProperty, @@ -14,7 +10,6 @@ const { } = primordials; const { exitCodes: { kGenericUserError } } = internalBinding('errors'); -const { ERR_ASYNC_CALLBACK } = require('internal/errors').codes; const async_wrap = internalBinding('async_wrap'); const { setCallbackTrampoline } = async_wrap; @@ -581,83 +576,9 @@ function triggerAsyncId() { const kNoPromiseHook = Symbol('kNoPromiseHook'); -// Minimal internal async hook used by Node.js internals (e.g. the inspector) -// that must create hooks without --enable-async-hooks. Unlike the public -// async_hooks.createHook() this does not support promise callbacks. -class AsyncHook { - constructor({ init, before, after, destroy }) { - if (init !== undefined && typeof init !== 'function') - throw new ERR_ASYNC_CALLBACK('hook.init'); - if (before !== undefined && typeof before !== 'function') - throw new ERR_ASYNC_CALLBACK('hook.before'); - if (after !== undefined && typeof after !== 'function') - throw new ERR_ASYNC_CALLBACK('hook.after'); - if (destroy !== undefined && typeof destroy !== 'function') - throw new ERR_ASYNC_CALLBACK('hook.destroy'); - - // Internal hooks never track promises. - this[kNoPromiseHook] = true; - this[init_symbol] = init; - this[before_symbol] = before; - this[after_symbol] = after; - this[destroy_symbol] = destroy; - } - - enable() { - const { 0: hooks_array, 1: hook_fields } = getHookArrays(); - - if (ArrayPrototypeIncludes(hooks_array, this)) - return this; - - const prev_kTotals = hook_fields[kTotals]; - - hook_fields[kTotals] = hook_fields[kInit] += +!!this[init_symbol]; - hook_fields[kTotals] += hook_fields[kBefore] += +!!this[before_symbol]; - hook_fields[kTotals] += hook_fields[kAfter] += +!!this[after_symbol]; - hook_fields[kTotals] += hook_fields[kDestroy] += +!!this[destroy_symbol]; - ArrayPrototypePush(hooks_array, this); - - if (prev_kTotals === 0 && hook_fields[kTotals] > 0) { - enableHooks(); - } - - return this; - } - - disable() { - const { 0: hooks_array, 1: hook_fields } = getHookArrays(); - - const index = ArrayPrototypeIndexOf(hooks_array, this); - if (index === -1) - return this; - - const prev_kTotals = hook_fields[kTotals]; - - hook_fields[kTotals] = hook_fields[kInit] -= +!!this[init_symbol]; - hook_fields[kTotals] += hook_fields[kBefore] -= +!!this[before_symbol]; - hook_fields[kTotals] += hook_fields[kAfter] -= +!!this[after_symbol]; - hook_fields[kTotals] += hook_fields[kDestroy] -= +!!this[destroy_symbol]; - ArrayPrototypeSplice(hooks_array, index, 1); - - if (prev_kTotals > 0 && hook_fields[kTotals] === 0) { - disableHooks(); - } - - return this; - } -} - -// Creates an internal AsyncHook without honoring --enable-async-hooks. Only for -// use by Node.js internals; userland goes through async_hooks.createHook(). -function createHook(fns) { - return new AsyncHook(fns); -} - module.exports = { executionAsyncId, triggerAsyncId, - // Create an async hook without honoring --enable-async-hooks (internals only). - createHook, // Private API getHookArrays, symbols: { diff --git a/lib/internal/inspector_async_hook.js b/lib/internal/inspector_async_hook.js index 4bafef870b78..4d5dd1b2fbe5 100644 --- a/lib/internal/inspector_async_hook.js +++ b/lib/internal/inspector_async_hook.js @@ -1,15 +1,41 @@ 'use strict'; +const { + ArrayPrototypeIncludes, + ArrayPrototypeIndexOf, + ArrayPrototypePush, + ArrayPrototypeSplice, +} = primordials; + +const { + getHookArrays, + enableHooks, + disableHooks, + symbols: { + init_symbol, + before_symbol, + after_symbol, + destroy_symbol, + }, + constants: { + kInit, + kBefore, + kAfter, + kDestroy, + kTotals, + }, + kNoPromiseHook, +} = require('internal/async_hooks'); + let hook; let config; function lazyHookCreation() { const inspector = internalBinding('inspector'); - const { createHook } = require('internal/async_hooks'); config = internalBinding('config'); - hook = createHook({ - init(asyncId, type, triggerAsyncId, resource) { + hook = { + [init_symbol](asyncId, type, triggerAsyncId, resource) { // It's difficult to tell which tasks will be recurring and which won't, // therefore we mark all tasks as recurring. Based on the discussion // in https://github.com/nodejs/node/pull/13870#discussion_r124515293, @@ -18,19 +44,59 @@ function lazyHookCreation() { inspector.asyncTaskScheduled(type, asyncId, recurring); }, - before(asyncId) { + [before_symbol](asyncId) { inspector.asyncTaskStarted(asyncId); }, - after(asyncId) { + [after_symbol](asyncId) { inspector.asyncTaskFinished(asyncId); }, - destroy(asyncId) { + [destroy_symbol](asyncId) { inspector.asyncTaskCanceled(asyncId); }, - trackPromises: false, - }); + + // The inspector does not want promise hook callbacks. + [kNoPromiseHook]: true, + + enable() { + const { 0: hooks_array, 1: hook_fields } = getHookArrays(); + + // Each hook is only allowed to be added once. + if (ArrayPrototypeIncludes(hooks_array, this)) + return; + + // This hook always registers all four callbacks, so each count is + // incremented exactly once. + const prev_kTotals = hook_fields[kTotals]; + hook_fields[kTotals] = hook_fields[kInit] += 1; + hook_fields[kTotals] += hook_fields[kBefore] += 1; + hook_fields[kTotals] += hook_fields[kAfter] += 1; + hook_fields[kTotals] += hook_fields[kDestroy] += 1; + ArrayPrototypePush(hooks_array, this); + + if (prev_kTotals === 0 && hook_fields[kTotals] > 0) + enableHooks(); + }, + + disable() { + const { 0: hooks_array, 1: hook_fields } = getHookArrays(); + + const index = ArrayPrototypeIndexOf(hooks_array, this); + if (index === -1) + return; + + const prev_kTotals = hook_fields[kTotals]; + hook_fields[kTotals] = hook_fields[kInit] -= 1; + hook_fields[kTotals] += hook_fields[kBefore] -= 1; + hook_fields[kTotals] += hook_fields[kAfter] -= 1; + hook_fields[kTotals] += hook_fields[kDestroy] -= 1; + ArrayPrototypeSplice(hooks_array, index, 1); + + if (prev_kTotals > 0 && hook_fields[kTotals] === 0) + disableHooks(); + }, + }; } function enable() { From eaa08c4e62d765d5417db1ec9a35e4e0783c9040 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Fri, 30 Oct 2026 17:42:50 +0000 Subject: [PATCH 3/7] doc: fix link ordering in errors.md The nodejs-links remark lint rule requires link definitions to be listed in alphabetical order. The `--enable-async-hooks` link added for the new flag was inserted before `--disable-proto=throw`; move it after so `make lint-md` passes. Refs: https://github.com/nodejs/node/pull/61030 Signed-off-by: Matteo Collina Assisted-by: pi --- doc/api/errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/errors.md b/doc/api/errors.md index c25838ca7b68..f09dc1a7a221 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -4784,8 +4784,8 @@ An error occurred trying to allocate memory. This should never happen. [`"exports"`]: packages.md#exports [`"imports"`]: packages.md#imports [`'uncaughtException'`]: process.md#event-uncaughtexception -[`--enable-async-hooks`]: cli.md#--enable-async-hooks [`--disable-proto=throw`]: cli.md#--disable-protomode +[`--enable-async-hooks`]: cli.md#--enable-async-hooks [`--force-fips`]: cli.md#--force-fips [`--no-addons`]: cli.md#--no-addons [`--unhandled-rejections`]: cli.md#--unhandled-rejectionsmode From cab4e3122dc9977d84f5accb6b9a4950b20e623b Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Sat, 31 Oct 2026 08:37:06 +0000 Subject: [PATCH 4/7] doc: keep async-hooks flag docs in alphabetical order The CLI options, the NODE_OPTIONS allowed-flags list, the config schema and the node.1 man page must list options in alphabetical order. Reorder the `--enable-async-hooks` entries added for the new flag so the ordering tests pass, and regenerate the config schema and node.1 man page. Refs: https://github.com/nodejs/node/pull/61030 Signed-off-by: Matteo Collina Assisted-by: pi --- doc/api/cli.md | 82 ++++++++++++++++++------------------- doc/node-config-schema.json | 4 ++ doc/node.1 | 64 ++++++++++++++--------------- 3 files changed, 77 insertions(+), 73 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index b6e05e57316a..45ed6ed18d79 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -139,46 +139,6 @@ Error: Cannot load native addon because loading addons is disabled. } ``` -### `--enable-async-hooks` - - - -Enable use of `async_hooks.createHook()`. This flag is required to enable -the `createHook` API, which is disabled by default. - -Example: - -```mjs -import { createHook } from 'node:async_hooks'; - -createHook({ init() {} }).enable(); -``` - -```cjs -const { createHook } = require('node:async_hooks'); - -createHook({ init() {} }).enable(); -``` - -```console -$ node index.js -node:async_hooks:160 - throw new ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED(); - ^ - -Error [ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED]: async_hooks.createHook() is disabled. Use --enable-async-hooks to enable it. - at createHook (node:async_hooks:160:11) - at Object. (/home/user/index.js:3:1) - ... -``` - -```console -$ node --enable-async-hooks index.js -# Works without error -``` - ### `--allow-child-process` + +Enable use of `async_hooks.createHook()`. This flag is required to enable +the `createHook` API, which is disabled by default. + +Example: + +```mjs +import { createHook } from 'node:async_hooks'; + +createHook({ init() {} }).enable(); +``` + +```cjs +const { createHook } = require('node:async_hooks'); + +createHook({ init() {} }).enable(); +``` + +```console +$ node index.js +node:async_hooks:160 + throw new ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED(); + ^ + +Error [ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED]: async_hooks.createHook() is disabled. Use --enable-async-hooks to enable it. + at createHook (node:async_hooks:160:11) + at Object. (/home/user/index.js:3:1) + ... +``` + +```console +$ node --enable-async-hooks index.js +# Works without error +``` + ### `--enable-fips` * `--allow-addons` -* `--enable-async-hooks` * `--allow-child-process` * `--allow-env` * `--allow-ffi` @@ -4333,6 +4332,7 @@ one is included in the list below. * `--disable-warning` * `--disable-wasm-trap-handler` * `--dns-result-order` +* `--enable-async-hooks` * `--enable-fips-indicator-events` * `--enable-fips` * `--enable-network-family-autoselection` diff --git a/doc/node-config-schema.json b/doc/node-config-schema.json index 0d2cb83b517d..3e4910da0cbe 100644 --- a/doc/node-config-schema.json +++ b/doc/node-config-schema.json @@ -311,6 +311,10 @@ "type": "string", "description": "set default value of verbatim in dns.lookup. Options are 'ipv4first' (IPv4 addresses are placed before IPv6 addresses) 'ipv6first' (IPv6 addresses are placed before IPv4 addresses) 'verbatim' (addresses are in the order the DNS resolver returned)" }, + "enable-async-hooks": { + "type": "boolean", + "description": "enable use of async_hooks.createHook" + }, "enable-fips": { "type": "boolean", "description": "enable FIPS crypto at startup" diff --git a/doc/node.1 b/doc/node.1 index 2d5a3b98efc0..75e7e4c3d605 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -86,36 +86,6 @@ Error: Cannot load native addon because loading addons is disabled. } .Ed . -.It Fl -enable-async-hooks -Enable use of \fBasync_hooks.createHook()\fR. This flag is required to enable -the \fBcreateHook\fR API, which is disabled by default. -Example: -.Bd -literal -import { createHook } from 'node:async_hooks'; - -createHook({ init() {} }).enable(); -.Ed -.Bd -literal -const { createHook } = require('node:async_hooks'); - -createHook({ init() {} }).enable(); -.Ed -.Bd -literal -$ node index.js -node:async_hooks:160 - throw new ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED(); - ^ - -Error [ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED]: async_hooks.createHook() is disabled. Use --enable-async-hooks to enable it. - at createHook (node:async_hooks:160:11) - at Object. (/home/user/index.js:3:1) - ... -.Ed -.Bd -literal -$ node --enable-async-hooks index.js -# Works without error -.Ed -. .It Fl -allow-child-process When using the Permission Model, the process will not be able to spawn any child process by default. @@ -774,6 +744,36 @@ Set the default value of \fBorder\fR in \fBdns.lookup()\fR and The default is \fBverbatim\fR and \fBdns.setDefaultResultOrder()\fR have higher priority than \fB--dns-result-order\fR. . +.It Fl -enable-async-hooks +Enable use of \fBasync_hooks.createHook()\fR. This flag is required to enable +the \fBcreateHook\fR API, which is disabled by default. +Example: +.Bd -literal +import { createHook } from 'node:async_hooks'; + +createHook({ init() {} }).enable(); +.Ed +.Bd -literal +const { createHook } = require('node:async_hooks'); + +createHook({ init() {} }).enable(); +.Ed +.Bd -literal +$ node index.js +node:async_hooks:160 + throw new ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED(); + ^ + +Error [ERR_ASYNC_HOOKS_CREATE_HOOK_DISABLED]: async_hooks.createHook() is disabled. Use --enable-async-hooks to enable it. + at createHook (node:async_hooks:160:11) + at Object. (/home/user/index.js:3:1) + ... +.Ed +.Bd -literal +$ node --enable-async-hooks index.js +# Works without error +.Ed +. .It Fl -enable-fips Enable FIPS mode at startup. A configured provider named \fBfips\fR must be available and initialize successfully. @@ -2216,8 +2216,6 @@ one is included in the list below. .It \fB--allow-addons\fR .It -\fB--enable-async-hooks\fR -.It \fB--allow-child-process\fR .It \fB--allow-env\fR @@ -2274,6 +2272,8 @@ one is included in the list below. .It \fB--dns-result-order\fR .It +\fB--enable-async-hooks\fR +.It \fB--enable-fips-indicator-events\fR .It \fB--enable-fips\fR From ce8dc67143cb6eb36b11619b5c1923d08d10d637 Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Sat, 31 Oct 2026 08:37:06 +0000 Subject: [PATCH 5/7] test: enable async hooks in async_hooks benchmark The async_hooks benchmarks call async_hooks.createHook(), which now requires `--enable-async-hooks`. Pass it through NODE_OPTIONS when running the benchmark test. Refs: https://github.com/nodejs/node/pull/61030 Signed-off-by: Matteo Collina Assisted-by: pi --- test/benchmark/test-benchmark-async-hooks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/benchmark/test-benchmark-async-hooks.js b/test/benchmark/test-benchmark-async-hooks.js index c9ea2c1e86db..22a0edd28934 100644 --- a/test/benchmark/test-benchmark-async-hooks.js +++ b/test/benchmark/test-benchmark-async-hooks.js @@ -10,4 +10,4 @@ if (!common.enoughTestMem) const runBenchmark = require('../common/benchmark'); -runBenchmark('async_hooks'); +runBenchmark('async_hooks', { NODE_OPTIONS: '--enable-async-hooks' }); From a6f673bc00f31af71732816bdd9ad4d9c53e936b Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Sat, 31 Oct 2026 12:31:40 +0000 Subject: [PATCH 6/7] test: enable async hooks in zlib async tests These tests call async_hooks.createHook() directly to count round trips or track the internal status, so they now need --enable-async-hooks. Refs: https://github.com/nodejs/node/pull/61030 Signed-off-by: Matteo Collina Assisted-by: pi --- test/parallel/test-zlib-convenience-async-round-trip.js | 1 + test/parallel/test-zlib-sync-without-options.js | 1 + 2 files changed, 2 insertions(+) diff --git a/test/parallel/test-zlib-convenience-async-round-trip.js b/test/parallel/test-zlib-convenience-async-round-trip.js index e7b9fb217b04..02cad394654c 100644 --- a/test/parallel/test-zlib-convenience-async-round-trip.js +++ b/test/parallel/test-zlib-convenience-async-round-trip.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks // The asynchronous convenience methods know the whole input up front, so they // process it with the finish flush in a single write. Check that a call whose // output fits in one output buffer takes exactly one threadpool round trip, diff --git a/test/parallel/test-zlib-sync-without-options.js b/test/parallel/test-zlib-sync-without-options.js index d155f9264429..23c79f090503 100644 --- a/test/parallel/test-zlib-sync-without-options.js +++ b/test/parallel/test-zlib-sync-without-options.js @@ -1,4 +1,5 @@ 'use strict'; +// Flags: --enable-async-hooks // Synchronous convenience methods called without options skip the stream and // reuse an internal output buffer. Check that they behave exactly like calls // that pass an empty options object, which go through the stream. From f04eec6effe2e99fcc3fa6dc6d6812be73df328b Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Sat, 31 Oct 2026 12:31:40 +0000 Subject: [PATCH 7/7] build: pass --enable-async-hooks in test-with-async-hooks Running tests with NODE_TEST_WITH_ASYNC_HOOKS=1 installs an async hook in test/common to verify ids. Now that async_hooks.createHook() requires --enable-async-hooks, pass the flag through the test runner so this target keeps working. Refs: https://github.com/nodejs/node/pull/61030 Signed-off-by: Matteo Collina Assisted-by: pi --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 0af75b42c293..eb7458b70bcb 100644 --- a/Makefile +++ b/Makefile @@ -807,6 +807,7 @@ test-with-async-hooks: ## Run tests with async hooks. $(MAKE) build-node-api-tests $(MAKE) cctest NODE_TEST_WITH_ASYNC_HOOKS=1 $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \ + --node-args=--enable-async-hooks \ $(JS_SUITES) \ $(NATIVE_SUITES)