nodejs / nodejs/node

Worker with large inline source map aborts process in V8 HandleDebugMagicComments

Offen
#64,155 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

v8 engine
Vorherrschende Sprache
JavaScript
Sterne
122k
Forks
37.3k
Ø Merge
4 T. 2 Std.
Gemergte PRs (30 T.)
283

Beschreibung

Version

v26.4.0

Platform
macOS 15.x arm64
Subsystem

worker_threads

What steps will reproduce the bug?

Create a worker entry file with a small amount of executable JavaScript and a very large inline sourceMappingURL=data:... comment, then load it in a worker with a constrained heap.

Minimal repro:

const fs = require("node:fs");
const os = require("node:os");
const path = require("node:path");
const { Worker } = require("node:worker_threads");

const dir = fs.mkdtempSync(path.join(os.tmpdir(), "node-inline-sourcemap-oom-"));

const workerPath = path.join(dir, "worker.cjs");

const source = [
  'const { parentPort } = require("node:worker_threads");',
  'parentPort.postMessage("loaded");',
  'parentPort.close();',
  "",
  "//# sourceMappingURL=data:application/json;base64,",
  "A".repeat(64 * 1024 * 1024),
  "",
].join("\n");

fs.writeFileSync(workerPath, source);

const worker = new Worker(workerPath, {
  resourceLimits: {
    maxOldGenerationSizeMb: 16,
  },
});

worker.on("message", console.log);

worker.on("error", console.error);

worker.on("exit", (code) => {
  console.log("exit", code);
  fs.rmSync(dir, { recursive: true, force: true });
});

Run: node repro.js

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

It reproduces consistently when the inline sourcemap comment is large enough relative to the worker heap limit.

For comparison, these do not reproduce the same fatal abort:

  1. Keeping the same large payload in an external worker.cjs.map file and using //# sourceMappingURL=worker.cjs.map.
  2. Putting a similarly large payload in a normal non-sourceMappingURL comment.
What is the expected behavior? Why is that the expected behavior?

The worker should fail gracefully, for example by emitting an error event or exiting with a worker failure, without aborting the entire Node.js process.

Ideally, parsing sourceMappingURL / debug magic comments should not internalize an arbitrarily large data URL into V8 old space during module compilation.

What do you see instead?

The whole Node process aborts with an out-of-memory fatal error before the worker can load the module.

Example stack from Node v26.4.0:

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
...
v8::internal::FactoryBase<v8::internal::Factory>::AllocateRawOneByteInternalizedString
v8::internal::FactoryBase<v8::internal::Factory>::NewOneByteInternalizedString
v8::internal::StringTable::LookupKey
v8::internal::FactoryBase<v8::internal::Factory>::InternalizeString
void v8::internal::Parser::HandleDebugMagicComments
v8::internal::Parser::ParseProgram
v8::internal::parsing::ParseProgram
v8::internal::Compiler::GetWrappedFunction
v8::ScriptCompiler::CompileFunction
node::contextify::CompileFunctionForCJSLoader
node::worker::Worker::Run
Additional information

No response

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit der bereitgestellten repro.js und dem Stack durch V8's Parser::HandleDebugMagicComments und vergleiche dann Inline- und externe Source Maps unter dem Worker-Heap-Limit. Verfolge den Worker-Einstieg über node::worker::Worker::Run und ermittle, wo die fatale Allokation auftritt. Als erledigt gilt die Aufgabe, wenn repro den Node.js-Prozess nicht mehr abbricht und der Worker den Fehler ordnungsgemäß meldet.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
javascript
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
42/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.