mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-10-25 06:33:13 +08:00
A single pathological file that hard-crashes the native indexer (SIGSEGV / stack overflow / abort / tree-sitter assertion) previously took down the whole MCP server or CLI (issue #668). index_repository now runs in a worker subprocess: the parent reaps it, and a crash is contained — the parent survives and reports it instead of dying. - src/mcp/index_supervisor.{h,c}: worker-role state + cbm_index_spawn_worker(), which spawns `<self> cli --index-worker index_repository <json> --response-out <tmp>` via the subprocess primitive, reaps, and classifies. fork+exec only; recursion is prevented by the --index-worker argv flag, never an ambient env var (which could misfire and silently run unprotected in-process). - src/mcp/mcp.c: a supervisor gate at the top of handle_index_repository wraps the run unless this process is the worker or CBM_INDEX_SUPERVISOR=0 (kill switch). Clean exit passes the worker's response through; a crash/hang returns a contained-failure response; a spawn failure degrades to the in-process path. - src/main.c: parse --index-worker / --response-out; the worker writes its result to the response file for the parent to read back. - src/ui/http_server.c: its existing index spawn now passes --index-worker so it does not re-supervise (one isolation layer, no redundant process nesting). - src/foundation/subprocess.c: the forked child redirects output with open()+dup2() instead of freopen() — async-signal-safe, no malloc between fork and exec, since the parent may be multithreaded (server threads + mimalloc/sqlite/libgit2 state). - internal/cbm/cbm.c: CBM_TEST_CRASH_ON / CBM_TEST_HANG_ON deterministic fault injectors (test-only, env-gated) so the guard is honest — green iff a real fault is genuinely contained, not a fixture that may stop faulting. - scripts/smoke-invariants.sh: inv_crasher_contained_cli asserts the crash escapes as a signal without the supervisor (rc>=128) and is contained + reported with it (rc<128, outcome=crash). Precise skip-and-continue (quarantine the culprit file, index the rest) is layered on in a follow-up; this change contains the crash and keeps the process alive. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>