fix(release): use panic=unwind so the plugin catch_unwind guard works #1

Merged
buildagent merged 1 commit from fix/release-panic-unwind into master 2026-06-04 14:28:43 +02:00
Member

Problem

The release profile set panic = "abort", which makes std::panic::catch_unwind a no-op — a panic aborts the process before it can be caught. That defeated the guard in parse_with_plugin (crates/indexer/src/index.rs), which wraps the tree-sitter plugin.extract() call in catch_unwind specifically so a panicking grammar degrades into a recorded parse_error row instead of crashing. In release builds, a single plugin panic would SIGABRT the whole long-lived daemon.

Fix

Switch [profile.release] to panic = "unwind", with an inline comment tying the setting to the guard so it isn't "optimized" back to abort. The other size optimizations (lto, codegen-units, strip) remain.

Verification

Proven end-to-end under the real [profile.release] via a throwaway --release --example that drives the production path (index_pathselect_pluginparse_with_plugincatch_unwind(plugin.extract)) with a plugin that panics in extract:

  • unwind: exit 0, panic caught, parse_error row written (IndexStats.parse_errors=1).
  • negative control (abort): exit 134 (SIGABRT) — confirms the regression is real and the probe discriminates.
  • Full workspace release build is clean.

Note: this regression is invisible to cargo test — the test harness forces panic = "unwind" regardless of the profile, which is why the abort setting slipped in unnoticed.

🤖 Generated with Claude Code

## Problem The release profile set `panic = "abort"`, which makes `std::panic::catch_unwind` a no-op — a panic aborts the process before it can be caught. That defeated the guard in `parse_with_plugin` (`crates/indexer/src/index.rs`), which wraps the tree-sitter `plugin.extract()` call in `catch_unwind` specifically so a panicking grammar degrades into a recorded `parse_error` row instead of crashing. **In release builds, a single plugin panic would SIGABRT the whole long-lived daemon.** ## Fix Switch `[profile.release]` to `panic = "unwind"`, with an inline comment tying the setting to the guard so it isn't "optimized" back to `abort`. The other size optimizations (`lto`, `codegen-units`, `strip`) remain. ## Verification Proven end-to-end **under the real `[profile.release]`** via a throwaway `--release --example` that drives the production path (`index_path` → `select_plugin` → `parse_with_plugin` → `catch_unwind(plugin.extract)`) with a plugin that panics in `extract`: - **unwind:** exit 0, panic caught, `parse_error` row written (`IndexStats.parse_errors=1`). - **negative control (abort):** exit 134 (SIGABRT) — confirms the regression is real and the probe discriminates. - Full workspace release build is clean. Note: this regression is **invisible to `cargo test`** — the test harness forces `panic = "unwind"` regardless of the profile, which is why the `abort` setting slipped in unnoticed. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(release): use panic=unwind so the plugin catch_unwind guard works
Some checks failed
CI / cargo fmt (pull_request) Successful in 35s
CI / cargo fmt (push) Successful in 28s
CI / cargo clippy (push) Has been cancelled
CI / cargo test (push) Has been cancelled
CI / cargo clippy (pull_request) Successful in 44s
CI / cargo test (pull_request) Failing after 2m49s
865bff4571
The release profile set panic="abort", which makes std::panic::catch_unwind
a no-op: a panic aborts the process before it can be caught. That defeated
the guard in parse_with_plugin (crates/indexer/src/index.rs), which wraps
the tree-sitter plugin.extract() call in catch_unwind specifically so a
panicking grammar degrades to a recorded parse_error row instead of taking
down the long-lived daemon. In release builds a single plugin panic would
SIGABRT the whole daemon.

Switch [profile.release] to panic="unwind" (with an inline comment tying it
to the guard) so the resilience the code already implements actually holds
in production. The other size optimizations (lto, codegen-units, strip)
remain.

Verified end-to-end under the real release profile via a throwaway
--release --example driving index_path with a panicking plugin: exit 0,
panic caught, parse_error row written. Negative control (panic="abort")
SIGABRTs (exit 134), confirming the discrimination. Note: this regression
is invisible to `cargo test` because the test harness forces panic=unwind
regardless of profile.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
buildagent deleted branch fix/release-panic-unwind 2026-06-04 14:28:43 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
h-dv/code-index!1
No description provided.