Repository navigation
FATAL ERROR: v8::FromJust Maybe value is Nothing #56020
Description
Activity
Hi, thanks for the report.
Would you mind adding the whole backtrace? Also a smaller repro case would be handy; like a code snippet.
Hi, thanks for the report.
Hi @juanarbol 👋🏼
Would you mind adding the whole backtrace?
Here is the full log:
FATAL ERROR: v8::FromJust Maybe value is Nothing ----- Native stack trace ----- 1: 0x100cc7d74 node::OnFatalError(char const*, char const*) 2: 0x100e58404 v8::api_internal::FromJustIsNothing() 3: 0x100d7f89c node::worker::Worker::JoinThread() 4: 0x100c69090 node::Environment::RunAndClearNativeImmediates(bool)::$_7::operator()(node::CallbackQueue<void, node::Environment*>*) const 5: 0x100c68788 node::Environment::RunAndClearNativeImmediates(bool) 6: 0x100c6ca50 node::Environment::InitializeLibuv()::$_1::__invoke(uv_async_s*) 7: 0x1016a1b30 uv__async_io 8: 0x1016b3c08 uv__io_poll 9: 0x1016a20f4 uv_run 10: 0x100bf16f0 node::SpinEventLoopInternal(node::Environment*) 11: 0x100d7f3c0 node::worker::Worker::Run() 12: 0x100d82a1c node::worker::Worker::StartThread(v8::FunctionCallbackInfo<v8::Value> const&)::$_3::__invoke(void*) 13: 0x19bfd9f94 _pthread_start [/usr/lib/system/libsystem_pthread.dylib] 14: 0x19bfd4d34 thread_start [/usr/lib/system/libsystem_pthread.dylib]
Also a smaller repro case would be handy; like a code snippet.
The minimum repro case is documented above, I wasn't able to make it smaller 🤷🏼 You need to run
nodefrom this repo, following the instructions above.Seems to be caused by the
Check()on thisobject()->Set(...):https://github.com/nodejs/node/blob/main/src/node_worker.cc#L457-L459
I'm not yet sure why. Maybe the object or context it belongs to is no longer valid at that point?
Strange...in this code:
object()->Set(env()->context(), env()->message_port_string(), Undefined(env()->isolate())).Check();object()is non-empty, and is not null or undefinedenv()->message_port_string()is a valid string with a value of "messagePort"Undefined(env()->isolate())produces a validundefined
And yet calling
Set(...)on theobject()fails 🤔Doing
v8::JSON::Stringify(...)onobject()yields an empty maybe.Seems like
object()is somehow something it should not be, and I'm not sure yet what. 🤔Seems to be triggering the immediate scheduled in
StartThreadafter the thread is stopped, but also after the isolate is disposed, which seems like a race condition of some sort.Worker(0:1034) Creating new worker instance with thread id 1 Worker(0:1034) Preparation for worker 1 finished Worker(0:1034) Creating isolate for worker with id 1 Worker(0:1043) Creating new worker instance with thread id 2 Worker(0:1043) Preparation for worker 2 finished Worker(0:1043) Creating isolate for worker with id 2 Worker(0:1034) Starting worker with id 1 Worker(0:1034) Worker 1 uses context from snapshot 1 Worker(0:1043) Starting worker with id 2 Worker(0:1043) Worker 2 uses context from snapshot 1 Worker(0:1034) Created Environment for worker with id 1 Worker(0:1034) Created message port for worker 1 Worker(0:1034) Loaded environment for worker 1 Worker(0:1043) Created Environment for worker with id 2 Worker(0:1043) Created message port for worker 2 Worker(0:1043) Loaded environment for worker 2 [20:52:29.821] INFO (55360): Starting the service "bug"... Worker(2:1519) Creating new worker instance with thread id 3 Worker(2:1519) Preparation for worker 3 finished Worker(2:1519) Creating isolate for worker with id 3 Worker(2:1526) Creating new worker instance with thread id 4 Worker(2:1526) Preparation for worker 4 finished Worker(2:1526) Creating isolate for worker with id 4 Worker(2:1519) Starting worker with id 3 Worker(2:1519) Worker 3 uses context from snapshot 1 Worker(2:1526) Starting worker with id 4 Worker(2:1526) Worker 4 uses context from snapshot 1 Worker(2:1519) Created Environment for worker with id 3 Worker(2:1519) Created message port for worker 3 Worker(2:1519) Loaded environment for worker 3 Worker(2:1526) Created Environment for worker with id 4 Worker(2:1526) Created message port for worker 4 Worker(2:1526) Loaded environment for worker 4 Worker(2:1519) Worker 3 called Exit(0, (null), (null)) Worker(2:1519) Exiting thread for worker 3 with exit code 0 Worker(2:1519) Worker 3 thread stops Worker(2:1519) Worker 3 dispose isolate Worker(0:1043) Worker 2 called Exit(1, (null), (null)) Worker(2:1526) Worker 4 called Exit(0, (null), (null)) Worker(2:1519) In cleanup immediate for worker 3 Worker(2:1526) Exiting thread for worker 4 with exit code 0 Worker(2:1519) before Worker(2:1519) object is empty: false Worker(2:1519) json is empty: true FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal ----- Native stack trace ----- Worker(2:1526) Worker 4 thread stops Worker(2:1526) Worker 4 dispose isolate 1: 0x10413ce10 node::OnFatalError(char const*, char const*) [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 2: 0x1042f2330 v8::api_internal::ToLocalEmpty() [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 3: 0x10420f1e0 node::worker::Worker::JoinThread() [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 4: 0x1040d2f10 node::Environment::RunAndClearNativeImmediates(bool)::$_0::operator()(node::CallbackQueue<void, node::Environment*>*) const [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 5: 0x1040d25c0 node::Environment::RunAndClearNativeImmediates(bool) [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 6: 0x1040d6bc0 node::Environment::InitializeLibuv()::$_0::__invoke(uv_async_s*) [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 7: 0x104ba5754 uv__async_io [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 8: 0x104bb83fc uv__io_poll [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 9: 0x104ba5cbc uv_run [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 10: 0x104054ac4 node::SpinEventLoopInternal(node::Environment*) [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 11: 0x10420eb20 node::worker::Worker::Run() [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 12: 0x1042121f8 node::worker::Worker::StartThread(v8::FunctionCallbackInfo<v8::Value> const&)::$_0::__invoke(void*) [/Users/stephenbelanger/Code/cpp/node/out/Release/node] 13: 0x18e1932e4 _pthread_start [/usr/lib/system/libsystem_pthread.dylib] 14: 0x18e18e0fc thread_start [/usr/lib/system/libsystem_pthread.dylib] zsh: abort NODE_DEBUG_NATIVE=worker ../../cpp/node/node ./node_modules/.bin/wattpm startNote the
In cleanup immediate for worker 3, which I added to test and match that up with otherworker 3lines.I don't know why this is happening, but the code is not safe.
At this point we are not allowed to call into JS, whichv8::Object::Setmay do.Yeah. That would seem to be the case. Not sure why we're doing this here an not somewhere else? Or if we even need to do it at all if the thread is getting disposed anyway?
This issues seems not to reproduce on v22+. It appears to be a race condition though, so I've opened a PR (#56191) anyway, which is not exactly a fix per se, but at least would ensure that particular crash doesn't happen again. Quite possibly deeper issues in there though as there seems to be a lack of thread coordination between the worker teardown paths.
Version
v20.18.0
Platform
Subsystem
No response
What steps will reproduce the bug?
Checkout the branch
chore/node/v8-fatal-error-reproductionof this repo. Then:You'll get:
How often does it reproduce? Is there a required condition?
Always.
If you add a comment on the 2nd call to
pino(line6), it doesn't occur.What is the expected behavior? Why is that the expected behavior?
Node should handle the shutdown differently, instead of throwing.
What do you see instead?
A stack trace of the error from v8
Additional information
I'm available to provide further information if this can help to fix the bug 😊
No response