Skip to content

SIGSEGV crash: LMDB reader slot leak causes MDB_READERS_FULL after multiple nvim sessions #664

Description

@imroc

Summary

fff.nvim's Rust extension segfaults with SIGSEGV when opening the file picker, caused by LMDB reader slot exhaustion (MDB_READERS_FULL).

Crash Banner

fff.nvim's rust extension hit a segfault and is about to die.
Please file the bug at https://github.com/dmtrKovalenko/fff/issues with this banner attached.
=== CRASH END SIGSEGV ===

Root Cause

fff.nvim leaks LMDB reader slots. Each Neovim session that loads fff.nvim occupies ~12-18 reader slots in the LMDB lock file (lock.mdb) but never releases them. The default maxreaders limit is 126, so after ~7-10 long-running nvim sessions, the reader table is exhausted.

When a new nvim session tries to open fff's file picker, LMDB returns MDB_READERS_FULL, which is not handled gracefully and leads to a segfault.

Log Evidence

From the fff log file (~/.local/state/nvim/fff+*.log):

2026-07-09T04:06:34.742389Z ERROR ThreadId(02) fff_nvim::error: string_value="Failed to start read transaction for frecency database: MDB_READERS_FULL: Environment maxreaders limit reached"

=== CRASH SIGSEGV (fff) ===
fff.nvim's rust extension hit a segfault and is about to die.
Please file the bug at https://github.com/dmtrKovalenko/fff/issues with this banner attached.
=== CRASH END SIGSEGV ===

Reader Slot Analysis

Parsing the LMDB lock file (~/.cache/nvim/fff_nvim/lock.mdb) shows all 126 reader slots occupied:

Max readers: 126
Used slots: 126 (alive=115, dead=11)
Free slots: 0

7 long-running nvim processes (running for 1-3 days) each leaked 12-18 reader slots:

PID Slots Leaked Process Age
1911588 16 ~1 day
2171829 17 ~1 day
2326348 17 ~1 day
2411364 17 ~1 day
573667 12 ~3 days
3123117 17 ~2 hours
2459610 18 ~1 day
3219827 6 (dead) crashed
Total 126/126

Note: clear_stale_readers() is called at env open, but it only reclaims slots from dead processes. Slots held by alive nvim processes are never released, even though each process should only need 1-2 reader slots at a time.

Reproduction

  1. Open multiple nvim sessions over time (7+ sessions running for 1+ days each)
  2. In a new nvim session, trigger the fff file picker (e.g., <leader><space> or ff)
  3. fff.nvim crashes with SIGSEGV, nvim exits

Environment

  • OS: Linux x86_64 (devcontainer, AMD EPYC 7K62)
  • Neovim version: built from source (LazyVim distribution)
  • fff.nvim version: 0.9.7-nightly.1a8ef35 (commit 1a8ef35)
  • Binary: prebuilt x86_64-unknown-linux-gnu.so downloaded from GitHub releases
  • Rustc (for local build fallback): 1.96.1

Workaround

Delete the LMDB lock file to reset the reader table:

rm -f ~/.cache/nvim/fff_nvim/lock.mdb
rm -f ~/.local/share/nvim/fff_queries/lock.mdb

This preserves the frecency data in data.mdb but resets all reader slots. LMDB recreates the lock file on next open.

Suggested Fix

The reader slot leak appears to be in the LMDB transaction handling — read transactions are opened but not properly closed/committed in some code paths, leaving reader slots occupied indefinitely. The clear_stale_readers() call at env open only helps with dead processes, not alive ones that have leaked slots.

Potential areas to investigate:

  • open_database_safe() in crates/fff-core/src/dbs/lmdb.rs — read transactions are committed, but if any code path opens additional read transactions without proper cleanup, slots leak
  • Background watcher / scan threads that may open read transactions
  • The SharedDb<T> refactor (commit 18f546b) that replaced two LMDB handles — may have introduced the leak

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions