| Filename | Latest commit message | Latest commit date |
|---|---|---|
Synced from monorepo Changes: - Workspace server: surface preview-proxy metrics through the hub metric pump - Shell: reclaim a session’s retained state in one entry - Shell: reclaim a session’s resident state in one entry - Pager: withhold key event types from Alacritty builds that double keys - Tools: cancel a session’s subagents when it closes - Pager: keep the whole plan in scrollback and separate reasoning from output in minimal mode - Pager: probe terminal version over DA2 and include it with feedback - SuperGrok Plus: identity, CLI, and analytics tier surfaces - Shell: inherit the session process scope into subagents - Pager: build @-file-search matcher lazily on first use - Tools: fix description and output contradictions in tool definitions - Workspace: degrade @-file-search instead of aborting on thread exhaustion - Tools: reap a session’s LSP servers when it closes - Tools: fix contradictions and defects in tool descriptions, schemas, and harness pools - MCP: reap stdio MCP children on session close - Shell: reuse spawn-time skill discovery for session telemetry - Tools: stop leaking shell-wrapper positional params into sourced scripts (fixes activate_conda under persistent/static shell) - Shell: self-heal corrupt session-search SQLite cache - Workspace: cap workspace-server tokio workers on many-core hosts - Shell: reap a session’s child processes when it closes - Crash handler: capture SIGABRT so panic-aborts leave crash reports - CLI chat proxy: team-scoped Grok Code managed-config admin routes - MCP: add CLI enable/disable for MCP servers - Shell: cap tokio worker threads for startup thread demand - Workspace: harden git_commit and add git_sync_base operation - Circuit breaker: add feature-gated gRPC retry policy Source-Revision: 2a818575225183d8ca915f5632a09b8067b5156a |
||
| .. | ||
| src | ||
| tests | ||
| Cargo.toml | ||
| README.md | ||
xai-crash-handler
Crash handler for SIGBUS/SIGSEGV with best-effort backtrace capture.
How it works
install() registers a sigaction handler. On crash it writes a binary blob (GCRX format) to crash_dir/last-crash.bin and restores the terminal via pre-computed escape sequences. The handler uses only async-signal-safe operations for file I/O, terminal restore, and re-raise.
On next launch, check_previous_crash() reads the blob, resolves IPs to symbols via backtrace, writes last-crash-report.txt, and archives it (keeping the last 5 reports).
No-ops on non-unix platforms. On musl-based Linux (release builds), the handler still records signal/address/version but skips frame capture since musl does not provide backtrace().
Limitations
Frame capture is best-effort
Frame capture uses two fully async-signal-safe techniques:
- The crash instruction pointer is extracted directly from the
ucontext_tpassed by the kernel. - Additional frames are captured by walking the frame-pointer chain (RBP on x86_64, x29 on aarch64) with raw pointer reads.
In release builds without -C force-frame-pointers, the frame-pointer chain may be incomplete or empty (the compiler omits frame pointers by default for optimization). The crash PC is always captured. In debug/dev builds, frame pointers are retained by default, producing fuller call stacks.
sigaltstack is per-thread
The alternate signal stack is installed only on the thread that calls install(). Tokio worker threads do not inherit it. Stack overflows on worker threads will still trigger the handler (sigaction is process-wide), but without altstack protection the handler itself may fault on the overflowed stack.
Usage
use std::path::PathBuf;
let crash_dir = PathBuf::from("/home/user/.myapp/crash");
// check_previous_crash MUST be called before install(), because
// install() opens last-crash.bin with O_TRUNC.
if let Some(r) = xai_crash_handler::check_previous_crash(&crash_dir) {
eprintln!("Crashed last session: {}", r.signal_name);
eprintln!("Report: {}", r.report_path.display());
}
// install() before any threads or async runtime — sigaltstack is per-thread.
// Creates crash_dir if it does not exist.
xai_crash_handler::install(xai_crash_handler::CrashHandlerConfig {
app_version: env!("CARGO_PKG_VERSION").to_string(),
crash_dir,
});