Skip to content
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

Heap snapshot crash when using worker_threads #43122

Closed
hyj1991 opened this issue May 17, 2022 · 1 comment
Closed

Heap snapshot crash when using worker_threads #43122

hyj1991 opened this issue May 17, 2022 · 1 comment
Labels
confirmed-bug Issues with confirmed bugs. worker Issues and PRs related to Worker support.

Comments

@hyj1991
Copy link

hyj1991 commented May 17, 2022

Version

v12.22.12 & v14.19.2 & v16.15.0

Platform

All

Subsystem

V8 engine

What steps will reproduce the bug?

function createSnapshot(filename) {
  const stream = require('fs').createWriteStream(filename);
  require('v8').getHeapSnapshot().pipe(stream);

}

function main() {
  const workerThreads = require('worker_threads');
  if (workerThreads.isMainThread) {
    const w = new workerThreads.Worker(__filename, {
      env: process.env,
    });

    w.once('exit', code => {
      createSnapshot('main.heapsnapshot');
      console.log(JSON.stringify({ code }));
    });
  } else {
    createSnapshot('worker_threads.heapsnapshot');
  }
}

main();

How often does it reproduce? Is there a required condition?

Always

What is the expected behavior?

No crashes.

What do you see instead?

Always crashed with SIGSEGV:

hyj1991@GDP-WIN3:~/test$ lldb /home/hyj1991/.tnvm/versions/node/v16.15.0/bin/node -c node.1652753197.core.18410
(lldb) target create "/home/hyj1991/.tnvm/versions/node/v16.15.0/bin/node" --core "node.1652753197.core.18410"
Core file '/home/hyj1991/test/node.1652753197.core.18410' (x86_64) was loaded.
(lldb) bt
* thread #1, name = 'node', stop reason = signal SIGSEGV
  * frame #0: 0x0000000000bcdfd7 node`node::worker::Worker::MemoryInfo(node::MemoryTracker*) const + 343
    frame #1: 0x0000000000a9ecd2 node`node::Environment::BuildEmbedderGraph(v8::Isolate*, v8::EmbedderGraph*, void*) + 2370
    frame #2: 0x000000000117f6ec node`v8::internal::HeapProfiler::BuildEmbedderGraph(v8::internal::Isolate*, v8::EmbedderGraph*) + 44
    frame #3: 0x000000000118ccf9 node`v8::internal::NativeObjectsExplorer::IterateAndExtractReferences(v8::internal::HeapSnapshotGenerator*) + 153
    frame #4: 0x000000000118e93f node`v8::internal::HeapSnapshotGenerator::GenerateSnapshot() + 495
    frame #5: 0x0000000001180246 node`v8::internal::HeapProfiler::TakeSnapshot(v8::ActivityControl*, v8::HeapProfiler::ObjectNameResolver*, bool, bool) + 134
    frame #6: 0x0000000000aa9b16 node`node::heap::CreateHeapSnapshotStream(v8::FunctionCallbackInfo<v8::Value> const&) + 118
    frame #7: 0x0000000000d552fe node`v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) + 926
    frame #8: 0x0000000000d5671f node`v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) + 175
    frame #9: 0x00000000015f2179 node`Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit + 57
    frame #10: 0x0000000001584b4a node`Builtins_InterpreterEntryTrampoline + 202
    frame #11: 0x0000000001584b4a node`Builtins_InterpreterEntryTrampoline + 202
    frame #12: 0x0000000001584b4a node`Builtins_InterpreterEntryTrampoline + 202
    frame #13: 0x0000000001584b4a node`Builtins_InterpreterEntryTrampoline + 202
    frame #14: 0x0000000001584b4a node`Builtins_InterpreterEntryTrampoline + 202
    frame #15: 0x0000000001584b4a node`Builtins_InterpreterEntryTrampoline + 202
    frame #16: 0x0000000001584b4a node`Builtins_InterpreterEntryTrampoline + 202
    frame #17: 0x0000000001582d58 node`Builtins_JSEntryTrampoline + 88
    frame #18: 0x0000000001582ae3 node`Builtins_JSEntry + 131
    frame #19: 0x0000000000e24418 node`v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) + 328
    frame #20: 0x0000000000e2526f node`v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) + 95
    frame #21: 0x0000000000d15112 node`v8::Function::Call(v8::Local<v8::Context>, v8::Local<v8::Value>, int, v8::Local<v8::Value>*) + 258
    frame #22: 0x0000000000a43295 node`node::InternalMakeCallback(node::Environment*, v8::Local<v8::Object>, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*, node::async_context) + 661
    frame #23: 0x0000000000a54029 node`node::AsyncWrap::MakeCallback(v8::Local<v8::Function>, int, v8::Local<v8::Value>*) + 121
    frame #24: 0x0000000000bcce1c node`node::worker::Worker::JoinThread() + 700
    frame #25: 0x0000000000a8a9f8 node`node::Environment::RunAndClearNativeImmediates(bool) + 1080
    frame #26: 0x0000000000a8addc node`node::Environment::InitializeLibuv()::'lambda'(uv_async_s*)::_FUN(uv_async_s*) + 60
    frame #27: 0x0000000001564936 node`uv__async_io(loop=0x00000000057f0860, w=<unavailable>, events=<unavailable>) at async.c:163:5
    frame #28: 0x0000000001577064 node`uv__io_poll(loop=0x0000000004a43c60, timeout=<unavailable>) at epoll.c:374:11
    frame #29: 0x0000000001565288 node`uv_run(loop=0x0000000004a43c60, mode=UV_RUN_DEFAULT) at core.c:389:5
    frame #30: 0x0000000000a43dd5 node`node::SpinEventLoop(node::Environment*) + 309
    frame #31: 0x0000000000b4bdb6 node`node::NodeMainInstance::Run(node::EnvSerializeInfo const*) + 406
    frame #32: 0x0000000000acd592 node`node::Start(int, char**) + 546
    frame #33: 0x00007f4e4a1c8c87 libc.so.6`__libc_start_main(main=(node`main), argc=2, argv=0x00007ffd6e0724c8, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007ffd6e0724b8) at libc-start.c:310
    frame #34: 0x0000000000a4067c node`_start + 41
(lldb)

Additional information

It crashes on all the latest LTS versions, I guess this is an incompatibility implementation between the worker_threads and v8.

@hyj1991 hyj1991 changed the title Heap snapshot crash with worker_threads Heap snapshot crash when use worker_threads May 17, 2022
@hyj1991 hyj1991 changed the title Heap snapshot crash when use worker_threads Heap snapshot crash when using worker_threads May 17, 2022
@legendecas legendecas added confirmed-bug Issues with confirmed bugs. worker Issues and PRs related to Worker support. labels May 17, 2022
@legendecas
Copy link
Member

legendecas commented May 17, 2022

I can reproduce the problem in the main branch. I'll take a look at this.

bengl pushed a commit that referenced this issue May 30, 2022
Worker.parent_port_ can be released before the exit event of Worker. The
parent_port_ is not owned by `node::worker::Worker`, thus the reference
to it is not always valid, and accessing it at exit crashes the process.

As the Worker.parent_port_ is only used in the memory info tracking, it
can be safely removed.

PR-URL: #43123
Fixes: #43122
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
juanarbol pushed a commit that referenced this issue May 31, 2022
Worker.parent_port_ can be released before the exit event of Worker. The
parent_port_ is not owned by `node::worker::Worker`, thus the reference
to it is not always valid, and accessing it at exit crashes the process.

As the Worker.parent_port_ is only used in the memory info tracking, it
can be safely removed.

PR-URL: #43123
Fixes: #43122
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
danielleadams pushed a commit that referenced this issue Jun 27, 2022
Worker.parent_port_ can be released before the exit event of Worker. The
parent_port_ is not owned by `node::worker::Worker`, thus the reference
to it is not always valid, and accessing it at exit crashes the process.

As the Worker.parent_port_ is only used in the memory info tracking, it
can be safely removed.

PR-URL: #43123
Fixes: #43122
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
targos pushed a commit that referenced this issue Jul 12, 2022
Worker.parent_port_ can be released before the exit event of Worker. The
parent_port_ is not owned by `node::worker::Worker`, thus the reference
to it is not always valid, and accessing it at exit crashes the process.

As the Worker.parent_port_ is only used in the memory info tracking, it
can be safely removed.

PR-URL: #43123
Fixes: #43122
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
targos pushed a commit that referenced this issue Jul 31, 2022
Worker.parent_port_ can be released before the exit event of Worker. The
parent_port_ is not owned by `node::worker::Worker`, thus the reference
to it is not always valid, and accessing it at exit crashes the process.

As the Worker.parent_port_ is only used in the memory info tracking, it
can be safely removed.

PR-URL: #43123
Fixes: #43122
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
guangwong pushed a commit to noslate-project/node that referenced this issue Oct 10, 2022
Worker.parent_port_ can be released before the exit event of Worker. The
parent_port_ is not owned by `node::worker::Worker`, thus the reference
to it is not always valid, and accessing it at exit crashes the process.

As the Worker.parent_port_ is only used in the memory info tracking, it
can be safely removed.

PR-URL: nodejs/node#43123
Fixes: nodejs/node#43122
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. worker Issues and PRs related to Worker support.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants