Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

WasmGC cumulative array allocations crash Node.js process with FATAL ERROR instead of trapping

Aberta
#64,981 3 comentários 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
4/5
Tempo estimado
3-5 dias
Facilidade para iniciantes
45/100
Tipo de issue
Bug
Clareza
Razoavelmente clara
Status de atividade
Pouca atividade
Stack de tecnologia
javascript, nodejs, wasm
Domínio
backend, devtools

Direção de pesquisa

Reproduza a falha com exhaust.wat, wasm-tools parse e test.js e, em seguida, inspecione o caminho de alocação de WasmGC em torno do heap do V8 e da pilha de OOM mostrada no relatório. Rastreie como a falha de alocação é reportada ao Node.js e verifique se a reprodução termina com um erro ou trap capturável, em vez de abortar o processo.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

blocked v8 engine
Version

24.2.0

Platform
Linux unknown387c76016c42.lan 6.19.14-108.fc42.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 21 18:06:59 UTC 2026 x86_64 GNU/Linux
Subsystem

No response

What steps will reproduce the bug?
  1. Save the attached exhaust.wat file
  2. Compile: wasm-tools parse exhaust.wat -o exhaust.wasm
  3. Run: node test.js
  4. Process crashes with FATAL ERROR + core dump

exhaust.wat:

(module
  (type $arr (array (mut i64)))
  (type $holder (array (mut (ref null $arr))))

  (func (export "exhaust") (param $count i32)
    (local $h (ref $holder))
    (local $i i32)

    ;; parent array to hold all refs (prevents GC collection)
    (array.new_default $holder (local.get $count))
    (local.set $h)

    (loop $loop
      ;; allocate ~1MB array (131072 x 8 bytes)
      (local.get $h)
      (local.get $i)
      (array.new_default $arr (i32.const 131072))
      (array.set $holder)

      ;; i++
      (local.get $i)
      (i32.const 1)
      (i32.add)
      (local.set $i)

      ;; loop while i < count
      (local.get $i)
      (local.get $count)
      (i32.lt_u)
      (br_if $loop)
    )
  )
)

test.js:

const fs = require('fs');
(async () => {
  const mod = await WebAssembly.compile(fs.readFileSync('exhaust.wasm'));
  const inst = await WebAssembly.instantiate(mod);
  console.log('Allocating 10,000 x 1MB...');
  inst.exports.exhaust(10000);
  console.log('Survived (should not reach here)');
})();
How often does it reproduce? Is there a required condition?

Fully reproducible.

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

The Wasm module should trap or throw a catchable JavaScript error on GC allocation failure, not crash the process with abort(). Linear memory already handles exhaustion gracefully (memory.grow returns -1), and the WasmGC spec allows implementations to "terminate that computation and report an embedder-specific error" on resource exhaustion.

What do you see instead?

Exit code: 134

Allocating 10,000 x 1MB...

<--- Last few GCs --->

[132127:0x365f6000]     1871 ms: Mark-Compact 4062.8 (4207.1) -> 4062.1 (4207.1) MB, pooled: 1 MB, 5.87 / 0.00 ms  (average mu = 0.944, current mu = 0.848) allocation failure; scavenge might not succeed
[132127:0x365f6000]     1891 ms: Mark-Compact 4095.1 (4240.3) -> 4095.0 (4240.3) MB, pooled: 1 MB, 7.87 / 0.00 ms  (average mu = 0.894, current mu = 0.604) allocation failure; scavenge might not succeed

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
----- Native stack trace -----

 1: 0xf1eeef node::OOMErrorHandler(char const*, v8::OOMDetails const&) [node]
 2: 0x1351da0 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, v8::OOMDetails const&) [node]
 3: 0x1351e8f v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, v8::OOMDetails const&) [node]
 4: 0x15e8505  [node]
 5: 0x15f968c v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
 6: 0x15cf2f3 v8::internal::HeapAllocator::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
 7: 0x15a5770 v8::internal::Factory::NewFillerObject(int, v8::internal::AllocationAlignment, v8::internal::AllocationType, v8::internal::AllocationOrigin) [node]
 8: 0x1a98558 v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [node]
 9: 0x21a1989  [node]
[1]    132127 IOT instruction (core dumped)  node test.js
Additional information

Bug found during the investigation on https://github.com/bytecodealliance/endive/issues/102

Linguagem predominante
JavaScript
Estrelas
122k
Forks
37.4k
Merge médio
4d 17h
PRs com merge (30d)
300

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de nodejs/node

Todas as issues de nodejs/node

Issues semelhantes

Mais issues de JavaScript

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.