Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#64,981 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
javascript, nodejs, wasm
Ambito
backend, devtools

Direzione di ricerca

Riproduci il fallimento con exhaust.wat, wasm-tools parse e test.js, quindi esamina il percorso di allocazione di WasmGC intorno all’heap V8 e allo stack OOM mostrato nel report. Traccia il modo in cui il fallimento dell’allocazione viene segnalato a Node.js e verifica che la riproduzione termini con un errore o trap intercettabile invece di interrompere il processo.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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

Lingua principale
JavaScript
Stelle
122k
Fork
37.4k
Merge medio
4g 3h
PR unite (30g)
279

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di nodejs/node

Tutte le issue di nodejs/node

Issue simili

Altre issue su JavaScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.