8000 Crash when array is growing to a normally valid size · Issue #49041 · nodejs/node · GitHub
  • [go: up one dir, main page]

    Skip to content

    Crash when array is growing to a normally valid size #49041

    @WRtux

    Description

    @WRtux

    Version

    v18.17.0

    Platform

    Microsoft Windows NT 10.0.19045.0 x64

    Subsystem

    No response

    What steps will reproduce the bug?

    // Safe
    /* try */ {
      let sparse = Array(130_000_000);
    
      for (let i = 0; i < sparse.length; ) {
        sparse[i] = i;
        if (++i % 1_000_000 === 0)
          console.log(i);
      }
    }
    
    // Safe, throws correctly
    try {
      let sparse = Array(140_000_000);
    
      for (let i = 0; i < sparse.length; ) {
        sparse[i] = i;
        if (++i % 1_000_000 === 0)
          console.log(i);
      }
    } catch (err) {
      console.error(err);
    }
    
    // Crash!
    {
      let dataset = [];
    
      for (let i = 0; i < 120_000_000; ) {
        dataset.push(i);
        if (++i % 1_000_000 === 0)
          console.log(i);
      }
    }
    

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

    Every time.

    What is the expected behavior? Why is that the expected behavior?

    No errors raised on the third case, or throwing RangeError: Invalid array length like the second case.

    What do you see instead?

    For the first two cases, memory is initially allocated on-the-go until reaching about 12M loops, when the rest of the full array is allocated at once (or throwing an error if exceeding the limit).

    For the last case, memory usage increases by step, and Node.js crashes a short time after the last increase (may need adding some delay in the snippet to slow down the process to see).

    Console log:

    1000000
    2000000
    ...
    11000000
    RangeError: Invalid array length
        at ...
    1000000
    2000000
    ...
    112000000
    
    #
    # Fatal error in , line 0
    # Fatal JavaScript invalid size error 169220804
    #
    #
    #
    #FailureMessage Object: 0000003FF3DFEC10
     1: 00007FF635E6B34F v8::internal::CodeObjectRegistry::~CodeObjectRegistry+123599
     2: 00007FF635D87F8F std::basic_ostream<char,std::char_traits<char> >::operator<<+65407
     3: 00007FF636A646C2 V8_Fatal+162
     4: 00007FF6365E78A5 v8::internal::FactoryBase<v8::internal::Factory>::NewFixedArray+101
     5: 00007FF6364A7D22 v8::Message::GetIsolate+16706
     6: 00007FF63631B7E1 v8::internal::CompilationCache::IsEnabledScriptAndEval+26913
     7: 00007FF6367BA061 v8::internal::SetupIsolateDelegate::SetupHeap+494417
     8: 000001F83E565AF5
    

    Additional information

    I've checked #47928 but I believe this is a problem beyond that. It seems that the buffer containing the array may try to grow to an invalid size if its size is changed dynamically, while it could still accommodate about 20M elements (by adding a check to limit size to grow to) before it really can't hold anything more. I find this quite annoying when I need to set a safe limit of element count and don't know how the arrays will be used in other places.

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      v8 engineIssues and PRs related to the V8 dependency.wrong repoIssues that should be opened in another repository.

      Type

      No type

      Projects

      No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

        0