From 2ba93e1db4992e73af42c47b445a54c2a767bd6e Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 31 Jul 2020 02:32:33 +0200 Subject: [PATCH] async_hooks: fix resource stack for deep stacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 460c81dc0e0 introduced a bug where the execution resource was not stored properly if we needed to call into C++ to extend the stack size. Fix that bug by always storing the resource. Refs: https://github.com/nodejs/node/pull/34319 Fixes: https://github.com/nodejs/node/issues/34556 PR-URL: https://github.com/nodejs/node/pull/34573 Reviewed-By: Andrey Pechkurov Reviewed-By: Benjamin Gruenbaum Reviewed-By: Gerhard Stöbich Reviewed-By: Gus Caplan --- lib/internal/async_hooks.js | 2 +- .../test-async-local-storage-deep-stack.js | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-async-local-storage-deep-stack.js diff --git a/lib/internal/async_hooks.js b/lib/internal/async_hooks.js index f4d4f1da49c4ca..9463d1d3348e67 100644 --- a/lib/internal/async_hooks.js +++ b/lib/internal/async_hooks.js @@ -499,11 +499,11 @@ function hasAsyncIdStack() { // This is the equivalent of the native push_async_ids() call. function pushAsyncContext(asyncId, triggerAsyncId, resource) { const offset = async_hook_fields[kStackLength]; + execution_async_resources[offset] = resource; if (offset * 2 >= async_wrap.async_ids_stack.length) return pushAsyncContext_(asyncId, triggerAsyncId); async_wrap.async_ids_stack[offset * 2] = async_id_fields[kExecutionAsyncId]; async_wrap.async_ids_stack[offset * 2 + 1] = async_id_fields[kTriggerAsyncId]; - execution_async_resources[offset] = resource; async_hook_fields[kStackLength]++; async_id_fields[kExecutionAsyncId] = asyncId; async_id_fields[kTriggerAsyncId] = triggerAsyncId; diff --git a/test/parallel/test-async-local-storage-deep-stack.js b/test/parallel/test-async-local-storage-deep-stack.js new file mode 100644 index 00000000000000..b5e1048d94a4ed --- /dev/null +++ b/test/parallel/test-async-local-storage-deep-stack.js @@ -0,0 +1,15 @@ +'use strict'; +const common = require('../common'); +const { AsyncLocalStorage } = require('async_hooks'); + +// Regression test for: https://github.com/nodejs/node/issues/34556 + +const als = new AsyncLocalStorage(); + +const done = common.mustCall(); + +function run(count) { + if (count !== 0) return als.run({}, run, --count); + done(); +} +run(1000);