镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

node crashes when v8.getHeapSnapshot is called in succession. #35559

Description

@PoojaDurgad
  • Version: v14.13.1
  • Platform: linux
  • Subsystem: v8

What steps will reproduce the bug?

// given code
const v8 = require('v8');
v8.getHeapSnapshot()
v8.getHeapSnapshot()

What is the expected behavior?

no crash, the API returns streams

Additional information

I can easily recreate it, so any more info can be collected if needed.

Activity

  1. joyeecheung commented on Oct 8, 2020

    @joyeecheung
    Member

    Can you post the stack trace here?

  2. added
    memoryIssues and PRs related to Node.js memory management or memory footprint.
    v8 moduleIssues and PRs related to the node:v8 module.
    on Oct 8, 2020
  3. PoojaDurgad commented on Oct 9, 2020

    @PoojaDurgad
    ContributorAuthor

    @joyeecheung - Thanks for the reply and here is the stack trace of the code.

    #1  0x0000000000fdb7b5 in v8::internal::wasm::WasmDecoder<(v8::internal::wasm::Decoder::ValidateFlag)1>::OpcodeLength(v8::internal::wasm::Decoder*, unsigned char const*) [clone .constprop.0] ()
    #2  0x000000000102d046 in v8::internal::wasm::DecodeLocalNames(v8::internal::Vector<unsigned char const>) ()
    #3  0x0000000000fdd1d9 in v8::internal::wasm::WasmCompilationUnit::CompileWasmFunction(v8::internal::Isolate*, v8::internal::wasm::NativeModule*, v8::internal::wasm::WasmFeatures*, v8::internal::wasm::WasmFunction const*, v8::internal::wasm::ExecutionTier) ()
    #4  0x0000000000fde268 in v8::internal::wasm::Decoder::errorf(unsigned int, char const*, ...) [clone .constprop.0] ()
    #5  0x0000000000fce530 in v8::internal::wasm::WasmFullDecoder<(v8::internal::wasm::Decoder::ValidateFlag)1, v8::internal::wasm::EmptyInterface>::DecodeNumericOpcode(v8::internal::wasm::WasmOpcode) ()
    #6  0x00000000009b4ea6 in v8::internal::(anonymous namespace)::SetLengthProperty(v8::internal::Isolate*, v8::internal::Handle<v8::internal::JSReceiver>, double) ()
    #7  0x0000000000be2f2b in v8::internal::Runtime_HasElementWithInterceptor(int, unsigned long*, v8::internal::Isolate*) ()
    #8  0x0000000000be44d6 in v8::internal::IC::UpdatePolymorphicIC(v8::internal::Handle<v8::internal::Name>, v8::internal::MaybeObjectHandle const&) ()
    #9  0x0000000000be4b56 in v8::internal::LoadIC::UpdateCaches(v8::internal::LookupIterator*) ()
    #10 0x00000000013feab9 in BLAKE2b_Final ()
    #11 0x0000000001397d62 in SSL_CTX_use_serverinfo_ex ()
    #12 0x0000000001397d62 in SSL_CTX_use_serverinfo_ex ()
    #13 0x0000000001397d62 in SSL_CTX_use_serverinfo_ex ()
    #14 0x0000000001397d62 in SSL_CTX_use_serverinfo_ex ()
    #15 0x0000000001397d62 in SSL_CTX_use_serverinfo_ex ()
    #16 0x0000000001397d62 in SSL_CTX_use_serverinfo_ex ()
    #17 0x0000000001397d62 in SSL_CTX_use_serverinfo_ex ()
    #18 0x0000000001397d62 in SSL_CTX_use_serverinfo_ex ()
    #19 0x0000000001395a7a in ssl_set_cert ()
    #20 0x0000000001395858 in ssl_do_config ()
    #21 0x0000000000cc0501 in v8::internal::(anonymous namespace)::ElementsAccessorBase<v8::internal::(anonymous namespace)::TypedElementsAccessor<(v8::internal::ElementsKind)20, short>, v8::internal::(anonymous namespace)::ElementsKindTraits<(v8::internal::ElementsKind)20> >::CopyTypedArrayElementsSlice(v8::internal::JSTypedArray, v8::internal::JSTypedArray, unsigned long, unsigned long) ()
    #22 0x0000000000cc136f in v8::internal::(anonymous namespace)::ElementsAccessorBase<v8::internal::(anonymous namespace)::TypedElementsAccessor<(v8::internal::ElementsKind)19, unsigned short>, v8::internal::(anonymous namespace)::ElementsKindTraits<(v8::internal::ElementsKind)19> >::CopyTypedArrayElementsSlice(v8::internal::JSTypedArray, v8::internal::JSTypedArray, unsigned long, unsigned long) ()
    #23 0x0000000000b89254 in v8::internal::YoungGenerationMarkingTask::MarkObject(v8::internal::Object) ()
    #24 0x00000000009cd906 in v8::internal::Builtin_Impl_Stats_ConsoleContext(int, unsigned long*, v8::internal::Isolate*) ()
    #25 0x00000000009cdb93 in v8::internal::Builtin_Impl_Stats_ConsoleTime(int, unsigned long*, v8::internal::Isolate*) ()
    #26 0x00000000009cf1f0 in v8::internal::Builtin_ConsoleTimeStamp(int, unsigned long*, v8::internal::Isolate*) ()
    #27 0x000000000096db6a in v8::debug::WasmScript::GetFunctionHash(int) ()
    #28 0x0000000000000000 in ?? ()
    
  4. addaleax commented on Oct 11, 2020

    @addaleax
    Member

    Just noticed that I ran into this independently of this issue – https://chromium-review.googlesource.com/c/v8/v8/+/2464823 fixes this.

  5. RaisinTen commented on Oct 11, 2020

    @RaisinTen
    Member

    @addaleax so is this a problem with the v8 GC or node?

  6. addaleax commented on Oct 11, 2020

    @addaleax
    Member

    @RaisinTen It’s a V8 bug, yes, not caused by the GC implementation but related to GC timing. We could work around it if necessary, but usually the V8 team responds very quickly during working hours (… faster than Node.js for sure 🙂 )

  7. RaisinTen commented on Oct 11, 2020

    @RaisinTen
    Member

    @addaleax 🙂
    I read it and this is what I understood:

    1. When we query the first snapshot object, it gets created and returned
    2. Then the second object is queried and the object creation is not complete yet
    3. Due to the GC timing, the second object gets deleted along with the first one before we actually get to handle the second object
    4. Now we are returned an address which we are not allowed to dereference, so we get a segfault

    Did I get it right? I don't think I understand how we can work around this though.

  8. addaleax commented on Oct 12, 2020

    @addaleax
    Member

    @RaisinTen Not quite… the process for creating a snapshot is:

    1. V8 starts creating the snapshot, adding some strings to the heap profiler’s internal string table
    2. V8 performs a GC, so that the heap snapshot does not contain objects that are not actually relevant to the snapshot
    3. V8 continues creating the snapshot, adding more strings to the internal string table
    4. Node.js wraps the snapshot (C++ object) in a JS object, using a weak reference – i.e. once the JS object is GC’ed, we delete the C++ snapshot object

    Now… that last bit is a bit tricky: V8 implements “Delete the snapshot object” in 2 different ways:

    1. If there is only one complete snapshot object, perform “delete all snapshot objects + reset metadata”, where “metadata” includes the internal string table
    2. If there are more complete snapshot objects, delete only the particular snapshot object in question.

    Part of the problem is the word “complete” here.

    Now, when running the script from the issue here …

    • During creation of the second snapshot, in step 2, V8 performs a GC.
    • Since the first snapshot is weakly held, this deletes it.
    • The delete operation also deletes metadata, because at that point, the first snapshot is the only complete one
    • In step 3, the second snapshot tries to access the internal string table – the one that was deleted just before this
    • The process crashes or hangs 💥
  9. RaisinTen commented on Oct 12, 2020

    @RaisinTen
    Member

    @addaleax thank you for the awesome explanation! 🙂

  10. added a commit that references this issue on Oct 14, 2020
  11. 6 remaining items

  12. added a commit that references this issue on Nov 22, 2020
  13. OmgImAlexis commented on Feb 15, 2021

    @OmgImAlexis

    Has this landed in a version of node yet?

    I'm trying to debug using chrome's "Allocation instrumentation on timeline" profile and it crashes with a segfault which looks similar to this. If it's not please let me know and I'll open my own issue. I commented here as it's the only thing I could find on google when searching for this.

    /usr/local/bin/node/unraid-api/node_modules/segfault-handler/build/Release/segfault-handler.node(+0x3276)[0x149965609276]
    /lib64/libpthread.so.0(+0x13690)[0x149966410690]
    unraid-api(_ZN2v88internal14V8HeapExplorer24ExtractContextReferencesEPNS0_9HeapEntryENS0_7ContextE+0xd6)[0x104ba06]
    unraid-api(_ZN2v88internal14V8HeapExplorer27IterateAndExtractReferencesEPNS0_21HeapSnapshotGeneratorE+0x385)[0x1050f75]
    unraid-api(_ZN2v88internal21HeapSnapshotGenerator16GenerateSnapshotEv+0xd4)[0x1051c14]
    unraid-api(_ZN2v88internal12HeapProfiler12TakeSnapshotEPNS_15ActivityControlEPNS_12HeapProfiler18ObjectNameResolverEb+0x6f)[0x1041bef]
    unraid-api(_ZN12v8_inspector23V8HeapProfilerAgentImpl16takeHeapSnapshotEN8v8_crdtp4glue6detail10ValueMaybeIbEES5_+0xf5)[0x12efe05]
    unraid-api(_ZN12v8_inspector23V8HeapProfilerAgentImpl23stopTrackingHeapObjectsEN8v8_crdtp4glue6detail10ValueMaybeIbEES5_+0x96)[0x12f10b6]
    unraid-api(_ZN12v8_inspector8protocol12HeapProfiler20DomainDispatcherImpl23stopTrackingHeapObjectsERKN8v8_crdtp12DispatchableEPNS0_15DictionaryValueEPNS3_12ErrorSupportE+0x191)[0x13cfb71]
    unraid-api[0x13ceede]
    unraid-api(_ZN8v8_crdtp14UberDispatcher14DispatchResult3RunEv+0x1b)[0x132875b]
    unraid-api(_ZN12v8_inspector22V8InspectorSessionImpl23dispatchProtocolMessageENS_10StringViewE+0x19f)[0x12f7f5f]
    unraid-api[0xb1774a]
    unraid-api[0xb374b9]
    unraid-api[0xb3572e]
    unraid-api[0xb35a81]
    unraid-api[0xb35d8d]
    unraid-api(_ZN4node11Environment21RunAndClearInterruptsEv+0x140)[0x9b2af0]
    unraid-api[0x9b2b58]
    unraid-api(_ZN2v88internal7Isolate27InvokeApiInterruptCallbacksEv+0x8b)[0xd0bdbb]
    unraid-api(_ZN2v88internal10StackGuard16HandleInterruptsEv+0x1fd)[0xd2379d]
    unraid-api(_ZN2v88internal18Runtime_StackGuardEiPmPNS0_7IsolateE+0x5a)[0x10cacfa]
    unraid-api[0x1483939]
    Segmentation fault
    
  14. addaleax commented on Feb 15, 2021

    @addaleax
    Member

    @OmgImAlexis The stack trace looks very different so I’d open a new issue. (And yes, the fix for this has been released on the latest 15.x and 14.x branches, but it’s unrelated to the Chrome feature anyway.)

  15. divasatanica commented on Aug 10, 2023

    @divasatanica

    @addaleax Hi, I met the same issue as @OmgImAlexis , can you post the link of the new issue you mentioned above? thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    memoryIssues and PRs related to Node.js memory management or memory footprint.v8 moduleIssues and PRs related to the node:v8 module.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions