-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Regression: Error: async hook stack has become corrupted (actual: 2, expected: 0) #34341
Comments
I will try to reduce the C code needed for reproduction. In particular, the |
This being N-API I did not recompile the addon for each commit. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
OK, it may not have been #32933. Bisect goes on. |
Looks like moving to V8 8.3.110.9 introduced the instability (in #32831). |
The problem also exists if we remove #include <stdio.h>
#include <assert.h>
#include <node_api.h>
static void delete_me(napi_env env, void* data, void* hint) {
napi_status status;
napi_value string;
napi_value error;
fprintf(stderr, "delete_me\n");
status = napi_create_string_utf8(env,
"Finalizer exception",
NAPI_AUTO_LENGTH,
&string);
assert(status == napi_ok);
status = napi_create_error(env, NULL, string, &error);
assert(status == napi_ok);
status = napi_throw(env, error);
assert(status == napi_ok);
}
static napi_value CreateException(napi_env env, napi_callback_info info) {
napi_value ret;
napi_status status = napi_create_external(env, NULL, delete_me, NULL, &ret);
assert(status == napi_ok);
return ret;
}
NAPI_MODULE_INIT() {
napi_value result;
napi_status status = napi_create_function(env,
"createException",
NAPI_AUTO_LENGTH,
CreateException,
NULL,
&result);
assert(status == napi_ok);
return result;
} |
The code can be reduced to #include <stdio.h>
#include <assert.h>
#include <node_api.h>
static void delete_me(napi_env env, void* data, void* hint) {
fprintf(stderr, "delete_me\n");
napi_status status = napi_throw_error(env, NULL, "Finalizer exception");
assert(status == napi_ok);
}
static napi_value CreateException(napi_env env, napi_callback_info info) {
napi_value ret;
napi_status status = napi_create_external(env, NULL, delete_me, NULL, &ret);
assert(status == napi_ok);
return ret;
}
NAPI_MODULE_INIT() {
napi_value result;
napi_status status = napi_create_function(env,
"createException",
NAPI_AUTO_LENGTH,
CreateException,
NULL,
&result);
assert(status == napi_ok);
return result;
} |
I set a hardware watchpoint at the location from which 0x00000000016d7317 in v8::internal::(anonymous namespace)::ElementsAccessorBase<v8::internal::(anonymous namespace)::TypedElementsAccessor<(v8::internal::ElementsKind)24, double>, v8::internal::(anonymous namespace)::ElementsKindTraits<(v8::internal::ElementsKind)24> >::Set (this=<optimized out>, holder=..., entry=..., value=...) at ../deps/v8/src/objects/elements.cc:3002
3002 static void SetImpl(ElementType* data_ptr, size_t entry, ElementType value) {
#0 0x00000000016d7317 in v8::internal::(anonymous namespace)::ElementsAccessorBase<v8::internal::(anonymous namespace)::TypedElementsAccessor<(v8::internal::ElementsKind)24, double>, v8::internal::(anonymous namespace)::ElementsKindTraits<(v8::internal::ElementsKind)24> >::Set (this=<optimized out>, holder=..., entry=..., value=...) at ../deps/v8/src/objects/elements.cc:3002
#1 0x00000000017f3d34 in v8::internal::LookupIterator::WriteDataValue (this=this@entry=0x7fffffffd130, value=value@entry=..., initializing_store=initializing_store@entry=false) at ../deps/v8/src/objects/objects.h:607
#2 0x000000000182eceb in v8::internal::Object::SetDataProperty (it=it@entry=0x7fffffffd130, value=value@entry=...) at ../deps/v8/src/objects/objects.cc:2760
#3 0x00000000018520d7 in v8::internal::Object::SetPropertyInternal (it=it@entry=0x7fffffffd130, value=..., should_throw=..., store_origin=store_origin@entry=v8::internal::StoreOrigin::kMaybeKeyed, found=found@entry=0x7fffffffd0c8) at ../deps/v8/src/objects/objects.cc:2546
#4 0x00000000018527f9 in v8::internal::Object::SetProperty (it=it@entry=0x7fffffffd130, value=value@entry=..., store_origin=store_origin@entry=v8::internal::StoreOrigin::kMaybeKeyed, should_throw=should_throw@entry=...) at ../deps/v8/src/objects/objects.cc:2565
#5 0x0000000001a28c3d in v8::internal::Runtime::SetObjectProperty (isolate=isolate@entry=0x5807010, object=object@entry=..., key=key@entry=..., value=..., store_origin=store_origin@entry=v8::internal::StoreOrigin::kMaybeKeyed, should_throw=..., should_throw@entry=...) at ../deps/v8/src/runtime/runtime-object.cc:427
#6 0x0000000001a366e4 in v8::internal::__RT_impl_Runtime_SetKeyedProperty (args=..., isolate=isolate@entry=0x5807010) at ../deps/v8/include/v8.h:9970
#7 0x0000000001a36a7a in v8::internal::Runtime_SetKeyedProperty (args_length=3, args_object=0x7fffffffd290, isolate=0x5807010) at ../deps/v8/src/runtime/runtime-object.cc:673
#8 0x0000000002050e80 in Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit () at ../../deps/v8/../../deps/v8/src/builtins/promise-misc.tq:111
#9 0x0000000002299ee3 in Builtins_StaKeyedPropertyHandler () at ../deps/v8/src/interpreter/interpreter-generator.cc:615
#10 0x00003f35de8765d9 in ?? ()
#11 0x0000000000000000 in ?? () |
@gabrielschulhof You can use |
@addaleax thanks! I'll try to produce a hybrid stack trace next. |
@gabrielschulhof That being said … it looks like you’re calling into JS/throwing an exception from the finalizer – that can’t be right? We allow that for |
@addaleax hmmm ... finalizers are supposed to be able to execute JS. Their signature accepts a |
@addaleax the original motivation was to make node-addon-api callbacks more consistent. In those headers we don't have |
@gabrielschulhof In that case, I would delay their execution with |
Throwing an exception from a finalizer can cause the following fatal error: Error: async hook stack has become corrupted (actual: 2, expected: 0) 1: 0x970b5a node::InternalCallbackScope::~InternalCallbackScope() [./node] 2: 0x99dda0 node::Environment::RunTimers(uv_timer_s*) [./node] 3: 0x13d8b22 [./node] 4: 0x13dbe42 uv_run [./node] 5: 0xa57974 node::NodeMainInstance::Run() [./node] 6: 0x9dbc17 node::Start(int, char**) [./node] 7: 0x7f4965417f43 __libc_start_main [/lib64/libc.so.6] 8: 0x96f4ae _start [./node] By nodejs#34341 (comment), calling into JS from a finalizer and/or throwing exceptions from there is not advised, because the stack may or may not be set up for JS execution. The best solution is to run the user's finalizer from a `SetImmediate()` callback. Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com> Fixes: nodejs#34341
Throwing an exception from a finalizer can cause the following fatal error: Error: async hook stack has become corrupted (actual: 2, expected: 0) 1: 0x970b5a node::InternalCallbackScope::~InternalCallbackScope() [./node] 2: 0x99dda0 node::Environment::RunTimers(uv_timer_s*) [./node] 3: 0x13d8b22 [./node] 4: 0x13dbe42 uv_run [./node] 5: 0xa57974 node::NodeMainInstance::Run() [./node] 6: 0x9dbc17 node::Start(int, char**) [./node] 7: 0x7f4965417f43 __libc_start_main [/lib64/libc.so.6] 8: 0x96f4ae _start [./node] By nodejs#34341 (comment), calling into JS from a finalizer and/or throwing exceptions from there is not advised, because the stack may or may not be set up for JS execution. The best solution is to run the user's finalizer from a `SetImmediate()` callback. Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com> Fixes: nodejs#34341
Throwing an exception from a finalizer can cause the following fatal error: Error: async hook stack has become corrupted (actual: 2, expected: 0) 1: 0x970b5a node::InternalCallbackScope::~InternalCallbackScope() [./node] 2: 0x99dda0 node::Environment::RunTimers(uv_timer_s*) [./node] 3: 0x13d8b22 [./node] 4: 0x13dbe42 uv_run [./node] 5: 0xa57974 node::NodeMainInstance::Run() [./node] 6: 0x9dbc17 node::Start(int, char**) [./node] 7: 0x7f4965417f43 __libc_start_main [/lib64/libc.so.6] 8: 0x96f4ae _start [./node] By nodejs#34341 (comment), calling into JS from a finalizer and/or throwing exceptions from there is not advised, because the stack may or may not be set up for JS execution. The best solution is to run the user's finalizer from a `SetImmediate()` callback. Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com> Fixes: nodejs#34341
Throwing an exception from a finalizer can cause the following fatal error: Error: async hook stack has become corrupted (actual: 2, expected: 0) 1: 0x970b5a node::InternalCallbackScope::~InternalCallbackScope() [./node] 2: 0x99dda0 node::Environment::RunTimers(uv_timer_s*) [./node] 3: 0x13d8b22 [./node] 4: 0x13dbe42 uv_run [./node] 5: 0xa57974 node::NodeMainInstance::Run() [./node] 6: 0x9dbc17 node::Start(int, char**) [./node] 7: 0x7f4965417f43 __libc_start_main [/lib64/libc.so.6] 8: 0x96f4ae _start [./node] By #34341 (comment), calling into JS from a finalizer and/or throwing exceptions from there is not advised, because the stack may or may not be set up for JS execution. The best solution is to run the user's finalizer from a `SetImmediate()` callback. Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com> Fixes: #34341 PR-URL: #34386 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Throwing an exception from a finalizer can cause the following fatal error: Error: async hook stack has become corrupted (actual: 2, expected: 0) 1: 0x970b5a node::InternalCallbackScope::~InternalCallbackScope() [./node] 2: 0x99dda0 node::Environment::RunTimers(uv_timer_s*) [./node] 3: 0x13d8b22 [./node] 4: 0x13dbe42 uv_run [./node] 5: 0xa57974 node::NodeMainInstance::Run() [./node] 6: 0x9dbc17 node::Start(int, char**) [./node] 7: 0x7f4965417f43 __libc_start_main [/lib64/libc.so.6] 8: 0x96f4ae _start [./node] By #34341 (comment), calling into JS from a finalizer and/or throwing exceptions from there is not advised, because the stack may or may not be set up for JS execution. The best solution is to run the user's finalizer from a `SetImmediate()` callback. Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com> Fixes: #34341 PR-URL: #34386 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Throwing an exception from a finalizer can cause the following fatal error: Error: async hook stack has become corrupted (actual: 2, expected: 0) 1: 0x970b5a node::InternalCallbackScope::~InternalCallbackScope() [./node] 2: 0x99dda0 node::Environment::RunTimers(uv_timer_s*) [./node] 3: 0x13d8b22 [./node] 4: 0x13dbe42 uv_run [./node] 5: 0xa57974 node::NodeMainInstance::Run() [./node] 6: 0x9dbc17 node::Start(int, char**) [./node] 7: 0x7f4965417f43 __libc_start_main [/lib64/libc.so.6] 8: 0x96f4ae _start [./node] By #34341 (comment), calling into JS from a finalizer and/or throwing exceptions from there is not advised, because the stack may or may not be set up for JS execution. The best solution is to run the user's finalizer from a `SetImmediate()` callback. Signed-off-by: Gabriel Schulhof <gabriel.schulhof@intel.com> Fixes: #34341 PR-URL: #34386 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
#32933 seems to have introduced the following error:
The error is produced by building the following add-on:
Tested with and without
--expose-gc
:Expected output for with
--expose-gc
– noneExpected output for without
--expose-gc
(repeated 20 times):The latter is expected because the thrown error is about
global.gc()
missing fromglobal
not about the error thrown from the native code, so itsanException.message
will not match the regex.A git bisect performed manually reveals that #32933 seems to have introduced some instability in the correct functioning of the above add-on:
Tested on my laptop (Fedora 30 x64).
The text was updated successfully, but these errors were encountered: