nodejs / nodejs/node

Concurrent PGlite WebAssembly initialization intermittently SIGSEGVs Node.js

オープン
#64,500 コメント 5 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
JavaScript
スター
122k
フォーク
37.4k
平均マージ
4日 3時間
マージ済み PR(30日)
272

説明

Version

v26.5.0 (also reproduced on Node 22, 24, 25)

Platform
The primary Docker reproduction ran on this host:


Linux dragon-pro18 6.18.35-1-cachyos-lts #1 SMP PREEMPT_DYNAMIC Sat, 13 Jun 2026 12:39:40 +0000 x86_64 GNU/Linux
Intel Core Ultra 9 285HX, 24 cores online


Docker replaces the userspace and Node installation but shares the host kernel and CPU. The same failure occurs with the host Node binary.
Subsystem

V8 / WebAssembly (observed through child_process)

What steps will reproduce the bug?

The minimal repository is:

https://github.com/gadicc/node-pglite-wasm-sigsegv-repro

It has one runtime dependency, @electric-sql/pglite@0.5.4. PGlite ships its PostgreSQL engine as WebAssembly; there is no native addon.

On a machine with at least 20 GiB available:

git clone https://github.com/gadicc/node-pglite-wasm-sigsegv-repro.git
cd node-pglite-wasm-sigsegv-repro
docker build -t pglite-node-sigsegv-repro .
docker run --rm pglite-node-sigsegv-repro

Equivalently, with a local Node installation:

npm ci
npm run repro

Each of 16 child processes independently creates an in-memory PGlite client, runs SELECT 1, awaits client.close() in finally, and exits. The parent repeats that wave up to 50 times and stops on the first failure. There is no Vitest, Vite, test runner, application code, native addon, IPC dependency, or database persistence.

The memory warning matters: the observed cgroup peak was approximately 19 GiB. The recorded failing run had oom=0 and oom_kill=0.

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

It is intermittent and requires concurrent processes in the measured setup.

Two clean Node 26 official-image runs failed at waves 13 and 8. Other results
without V8 CLI overrides were:

Node Result
25 1/20 waves failed
24 4/45 waves failed
22 1/10 waves failed
20 0/40 waves failed

The Node 20 result is a non-reproduction in an intermittent test, not evidence that it is unaffected. Official Node 20, 22, 24, and 26 images expose the same relevant defaults: Liftoff, lazy compilation, dynamic tiering, and WASM tier-up are enabled, with up to 128 compilation tasks. Node 20 did reproduce with --no-liftoff, which forces the optimizing compiler.

The Node 27 V8 canary failed at wave 17 with child_process.fork() and failed 2/50 waves with ordinary child_process.spawn(). A sequential one-child control passed 50/50 waves.

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

Every child should complete the query, close the PGlite client, and exit with code 0.

What do you see instead?

An intermittent child is terminated by SIGSEGV:

node=v26.5.0 v8=14.6.202.34-node.24 platform=linux arch=x64 children=16 waves=50
wave=1 passed=16/16
...
wave=8 passed=15/16
child=10 code=null signal=SIGSEGV elapsedMs=4315
failedWaves=1 completedWaves=8 requestedWaves=50
Additional information

Native diagnostics from a sanitized-environment reproduction:

  1. strace recorded an initial SIGSEGV with SEGV_MAPERR at a large guarded WASM address.
  2. Node's node::TrapWebAssemblyOrContinue called raise(SIGSEGV) after V8 declined to handle the address as a valid WASM trap.
  3. The retained core records the resulting SI_TKILL signal.
  4. GDB placed another crash in the lazy WASM compilation path through LiftoffAssembler::PrepareCall, ExecuteLiftoffCompilation, CompileLazy, and Runtime_WasmCompileLazy, with background Turboshaft compilation active. A separate retained crash was in v8::internal::MarkingBarrier::MarkValueLocal.

Relevant flag controls on Node 25:

  • default: reproduced;
  • --wasm-enforce-bounds-checks: reproduced;
  • --wasm-num-compilation-tasks=1: reproduced;
  • --no-wasm-tier-up: passed 100/100 waves in that version;
  • --no-liftoff: reproduced.

The Node 27 canary nevertheless reproduced with both --no-wasm-tier-up and --liftoff-only, so no single WASM tier is universally required.

I also built the exact PGlite 0.5.4 tag using its official pnpm build:all:debug workflow. That PostgreSQL WASM used -g,
-gsource-map, and --no-wasm-opt; LLVM verified 1,322 DWARF compilation units without errors. With Node 25.2.1, a sequential control passed 5/5 waves and eight concurrent children passed 5/5 waves, while 16 concurrent children
reproduced SIGSEGV in wave 2. The cgroup peak was 67,306,729,472 bytes (62.7 GiB), with oom=0 and oom_kill=0.

Runtime controls using the same PGlite version and concurrency:

  • Bun 1.3.11 / JavaScriptCore: 50/50 waves passed;
  • Deno 2.8.0 / V8 14.9.207.2, default: 50/50 passed;
  • Deno 2.8.0 / V8 14.9.207.2, --no-liftoff: 50/50 passed.

The evidence therefore establishes a Node-runtime-specific interaction in the tested configurations, but does not yet distinguish Node's WASM trap/embedding layer or build configuration from a V8 defect exposed by Node. d8 is V8's standalone JavaScript shell; reproducing there without Node or its APIs would prove that the bug exists independently in V8. I would appreciate guidance on whether this should be routed or cross-filed to V8.

On 2026-07-14 I searched open Node and V8 reports for PGlite, TrapWebAssemblyOrContinue, WasmCompileLazy, LiftoffAssembler, and concurrent WASM SIGSEGVs, and found no exact duplicate. The reproduction README records the related but materially different reports.

Lastly,

  • Co-authored with Codex gpt-5.6-sol, reasoning: high, with significant human input.
  • This issue was opened by me personally by hand and without any automation.

Edit 1: Added PGLite debug build info in "Additional Information" above.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

リンクされた node-pglite-wasm-sigsegv-repro をクローンして実行し、まず文書化されている Docker または npm による再現と、その逐次的な制御から始めます。失敗する Node の動作を d8 と比較し、その後、言及されている node::TrapWebAssemblyOrContinue と V8 の遅延 WASM コンパイルのパスを調査します。Node と V8 のどちらに不具合が属するかを特定し、再現可能なリグレッションケースを含む、確認済みの修正またはルーティングの推奨を提示できれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
docker, javascript, nodejs, wasm
領域
backend, compilers, operating-systems
issue の種類
バグ
難易度
5/5
見積もり時間
1週間以上
活発さ
活発
明瞭さ
説明が足りない
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。