Summary
codegraph init / codegraph index dies with Segmentation fault (core dumped) — the entire CLI process, not just a parse worker — when the tree contains a C/C++ file with very deep brace nesting.
The crash is a native stack overflow in codegraph-kernel.node, hit inside a parse worker. Parse workers are created without resourceLimits, so they get Node's default 4 MB thread stack (the main thread gets 8 MB). A native stack overflow cannot be caught by the JS layer the way a WASM abort can, and because worker threads share the process, the overflow takes the whole codegraph process down — no error message, no per-file fallback, no partial index.
Repro'd on llvm/llvm-project (31,608 scanned files), where the offending file is clang/test/Parser/parser_overflow.c — a clang regression test that deliberately nests 16,384 {.
- codegraph: v1.5.0 (npm bundle,
lib/kernel/codegraph-kernel.node)
- node: v24.18.0
- platform: Linux 5.15.0 x86_64, 64 cores, 247 GB RAM
Reproduction
Self-contained, no llvm checkout needed. Any C file with ~10k nested braces does it:
python3 -c "d=16384; open('deep.c','w').write('void foo(void) {\n'+'{'*d+'}'*d+'\n}\n')"
codegraph init .
│ ◆ Scanning files — 1 found
│ · Parsing code ████████████░░░░░░░░░░░░ 50%
[1] 2903910 segmentation fault (core dumped)
Minimal direct repro against the kernel, with the stack size as the only variable:
// one.js — node one.js <file> [stackSizeMb]
const { Worker, isMainThread, workerData } = require('worker_threads');
const fs = require('fs');
if (isMainThread) {
const stackMb = process.argv[3] ? parseFloat(process.argv[3]) : null;
const w = new Worker(__filename, {
workerData: { file: process.argv[2] },
resourceLimits: stackMb ? { stackSizeMb: stackMb } : undefined,
});
w.on('exit', (code) => console.log(`stackMb=${stackMb ?? 'default(4)'} exitCode=${code}`));
} else {
const LIB = '<...>/codegraph/versions/v1.5.0/lib/dist/extraction';
const { detectLanguage } = require(LIB + '/grammars');
const { tryKernelExtractRaw } = require(LIB + '/kernel');
const content = fs.readFileSync(workerData.file, 'utf8');
const r = tryKernelExtractRaw(workerData.file, content, detectLanguage(workerData.file, content));
console.log('parsed ok, nodes =', r ? r.counts.nodes : 'deferred');
}
$ node one.js deep.c # default 4 MB worker stack
Segmentation fault (core dumped) # rc=139
$ node one.js deep.c 4 # rc=139
$ node one.js deep.c 6 # rc=139
$ node one.js deep.c 8 # parsed ok, nodes = 2 exitCode=0
$ node one.js deep.c 64 # parsed ok, nodes = 2 exitCode=0
Relevant code
dist/extraction/parse-pool.js:131 — this.createWorker = () => new Worker(scriptPath); — no resourceLimits, so the parse worker runs on Node's default 4 MB stack.
dist/extraction/parse-worker.js:90 — tryKernelExtractRaw(filePath, content, language), the call that faults.
dist/extraction/kernel/index.js — DEFAULT_ROUTED includes c / cpp (R7a, 2026-07-17), so C/C++ takes the kernel path by default.
dist/extraction/parse-worker.js:112-119 — the catch that handles WASM memory failures; unreachable for a native SIGSEGV.
Workarounds for anyone hitting this now
CODEGRAPH_KERNEL=0 codegraph index . # WASM path, ~25% slower, parses the file correctly
or exclude the file in codegraph.json:
{ "exclude": ["clang/test/Parser/parser_overflow.c"] }
Any repo carrying parser stress-test fixtures is exposed — clang, gcc test suites, fuzzer corpora.
Summary
codegraph init/codegraph indexdies withSegmentation fault (core dumped)— the entire CLI process, not just a parse worker — when the tree contains a C/C++ file with very deep brace nesting.The crash is a native stack overflow in
codegraph-kernel.node, hit inside a parse worker. Parse workers are created withoutresourceLimits, so they get Node's default 4 MB thread stack (the main thread gets 8 MB). A native stack overflow cannot be caught by the JS layer the way a WASM abort can, and because worker threads share the process, the overflow takes the wholecodegraphprocess down — no error message, no per-file fallback, no partial index.Repro'd on
llvm/llvm-project(31,608 scanned files), where the offending file isclang/test/Parser/parser_overflow.c— a clang regression test that deliberately nests 16,384{.lib/kernel/codegraph-kernel.node)Reproduction
Self-contained, no llvm checkout needed. Any C file with ~10k nested braces does it:
Minimal direct repro against the kernel, with the stack size as the only variable:
Relevant code
dist/extraction/parse-pool.js:131—this.createWorker = () => new Worker(scriptPath);— noresourceLimits, so the parse worker runs on Node's default 4 MB stack.dist/extraction/parse-worker.js:90—tryKernelExtractRaw(filePath, content, language), the call that faults.dist/extraction/kernel/index.js—DEFAULT_ROUTEDincludesc/cpp(R7a, 2026-07-17), so C/C++ takes the kernel path by default.dist/extraction/parse-worker.js:112-119— the catch that handles WASM memory failures; unreachable for a native SIGSEGV.Workarounds for anyone hitting this now
or exclude the file in
codegraph.json:{ "exclude": ["clang/test/Parser/parser_overflow.c"] }Any repo carrying parser stress-test fixtures is exposed — clang, gcc test suites, fuzzer corpora.