Skip to content

feat(store): expose mmap_size via CBM_SQLITE_MMAP_SIZE env#315

Open
edwardmhughes wants to merge 1 commit intoDeusData:mainfrom
edwardmhughes:fix/mmap-env-knob
Open

feat(store): expose mmap_size via CBM_SQLITE_MMAP_SIZE env#315
edwardmhughes wants to merge 1 commit intoDeusData:mainfrom
edwardmhughes:fix/mmap-env-knob

Conversation

@edwardmhughes
Copy link
Copy Markdown

Summary

Hard-coded PRAGMA mmap_size = 67108864 left no path for users running multiple codebase-memory-mcp instances against the same cache to opt out of memory-mapped I/O.

On macOS, when one instance's checkpoint or reindex truncates the DB file under another instance's live mmap, accessing the now-missing pages raises SIGBUS, which takes down the process. Setting CBM_SQLITE_MMAP_SIZE=0 reverts to read()/pread() I/O, which returns recoverable SQLITE_IOERR instead.

Changes

  • src/store/store.c: Extracts cbm_store_resolve_mmap_size() — reads CBM_SQLITE_MMAP_SIZE, validates with strtoll, clamps negative to 0, falls back to default 67108864 on missing/malformed input
  • src/store/store.h: Declares cbm_store_resolve_mmap_size() for tests
  • tests/test_store_pragmas.c (new): 7 tests covering default, zero, explicit value, negative clamp, garbage input, partial garbage, and store-open smoke test
  • Makefile.cbm + tests/test_main.c: Wire new test suite

Behavior

Scenario Before After
CBM_SQLITE_MMAP_SIZE unset PRAGMA mmap_size = 67108864 unchanged
CBM_SQLITE_MMAP_SIZE=0 n/a PRAGMA mmap_size = 0 (disables mmap)
CBM_SQLITE_MMAP_SIZE=1048576 n/a PRAGMA mmap_size = 1048576
Invalid value n/a logs warning, falls back to 67108864

Single-instance users: no behavior change.

Fixes #314

Hard-coded `PRAGMA mmap_size = 67108864` in configure_pragmas() left
no path for users running multiple cbm-mcp instances against the
same cache to opt out of memory-mapped I/O. On macOS, when one
instance's checkpoint or reindex truncates the DB file under
another instance's live mmap, accessing the now-missing pages
raises SIGBUS, taking the process down.

Setting CBM_SQLITE_MMAP_SIZE=0 reverts to read()/pread() I/O,
which returns recoverable SQLITE_IOERR instead of crashing the
process.

- Default unchanged (67108864 / 64 MB). No behavior change for
  single-instance users.
- Malformed values (non-numeric, partial-numeric) fall back to
  the default rather than failing the store open.
- Negative values clamp to 0.
- New tests: tests/test_store_pragmas.c covers all five resolver
  paths plus an integration smoke that opens a file-backed store
  with mmap disabled.

Empirical evidence: 9 SIGBUS crash reports collected on macOS
arm64 v0.6.0 in a 14-hour window, all signature 'cluster_pagein
past EOF' with stacks bottoming in SQLite btree code under the
watcher thread's incremental-index pipeline.
@DeusData DeusData added enhancement New feature or request stability/performance Server crashes, OOM, hangs, high CPU/memory labels May 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request stability/performance Server crashes, OOM, hangs, high CPU/memory

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SIGBUS on macOS arm64 when 2+ sessions share the same cache dir

2 participants