Rust bindings for Google Crashpad crash reporting system.
| Directory | Package Name | Description |
|---|---|---|
crashpad-sys/ |
crashpad-rs-sys |
Low-level FFI bindings to Crashpad C++ library |
crashpad/ |
crashpad-rs |
Safe Rust wrapper API |
Note: The directories are published with different names to avoid conflicts on crates.io:
crashpad-sys/→crashpad-rs-syscrashpad/→crashpad-rs
- Cross-platform: macOS, Linux, iOS, Android, Windows
- Safe API: Rust-safe wrapper around Crashpad C++ library
- Flexible Configuration: Runtime handler configuration
- Native Crash Handler Included: Handler executable built-in
- Multiple Build Strategies: Choose between source build or pre-compiled binaries
- Automatic Handler Distribution: Optional bundler for seamless deployment
Add to your Cargo.toml:
[dependencies]
# x-release-please-start-version
crashpad-rs = "0.2.7"
# x-release-please-end-version
# Optional: For automatic handler bundling at build time
[build-dependencies]
# x-release-please-start-version
crashpad-handler-bundler = "0.2.7"
# x-release-please-end-versionThe crashpad-rs-sys crate supports three mutually exclusive build strategies:
| Strategy | Description | Platform Support | Requirements |
|---|---|---|---|
vendored (default) |
Builds from submodules with pinned versions | Linux, macOS, iOS, Android (❌ Windows) | Git submodules |
vendored-depot |
Builds using Google's depot_tools with latest sources | All platforms (✅ Windows tested) | Python 3.8+, depot_tools |
prebuilt |
Uses pre-compiled binaries from GitHub Releases | Linux (x86_64, aarch64), macOS (x86_64, aarch64), Windows (x86_64) | Network access |
Choose a strategy by enabling the corresponding feature:
# Use pre-compiled binaries (fastest build)
crashpad-rs = { version = "0.2.6", features = ["prebuilt"] }
# Use depot_tools for Windows builds
crashpad-rs = { version = "0.2.6", features = ["vendored-depot"] }
# Default: vendored (builds from submodules)
crashpad-rs = "0.2.6"Note:
vendoredis the default and recommended for most platforms except Windowsvendored-depotis required for Windows native buildsprebuiltprovides fastest builds but requires pre-built archives for your platform
If using the bundler, create a build.rs:
fn main() {
// Automatically copy crashpad_handler to target directory
crashpad_handler_bundler::bundle().expect("Failed to bundle handler");
}use crashpad_rs::{CrashpadClient, CrashpadConfig};
use std::collections::HashMap;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize the Crashpad client
let client = CrashpadClient::new()?;
// Configure crash reporting
// If using crashpad-handler-bundler, the handler path is available via env var
let handler_path = option_env!("CRASHPAD_HANDLER_PATH")
.unwrap_or("./crashpad_handler");
let config = CrashpadConfig::builder()
.handler_path(handler_path) // Handler executable
.database_path("./crashes") // Local crash storage
.url("https://your-crash-server.com/submit") // Upload endpoint
.build();
// Add application metadata
let mut annotations = HashMap::new();
annotations.insert("version".to_string(), env!("CARGO_PKG_VERSION").to_string());
annotations.insert("build".to_string(), "release".to_string());
// Start crash monitoring
client.start_with_config(&config, &annotations)?;
// Your application code here
Ok(())
}// Minimal config - crashes saved locally, no upload
let config = CrashpadConfig::builder()
.handler_path("./crashpad_handler") // Required on desktop platforms
.database_path("./crash_dumps") // Where to store crash dumps
.build();// Full configuration with upload server
let config = CrashpadConfig::builder()
.handler_path(std::env::var("CRASHPAD_HANDLER")
.unwrap_or_else( | _ | "./crashpad_handler".to_string()))
.database_path("/var/crash/myapp")
.metrics_path("/var/metrics/myapp") // Optional: metrics storage
.url("https://crashes.example.com/api/minidump")
.build();// Handler path is required for desktop platforms
let config = CrashpadConfig::builder()
.handler_path("./crashpad_handler") // Must point to handler executable
.database_path("./crashes")
.build();// iOS uses in-process handler - no handler_path needed
let config = CrashpadConfig::builder()
.database_path("./crashes") // Relative to app's Documents directory
.url("https://crashes.example.com/api/minidump")
.build();// Android can use external handler (as .so file in APK)
let config = CrashpadConfig::builder()
.handler_path("./libcrashpad_handler.so") // Renamed for APK distribution
.database_path("/data/data/com.example.app/crashes")
.build();// Adjust configuration based on environment
let config = if cfg!(debug_assertions) {
// Development: local storage only, no rate limiting
CrashpadConfig::builder()
.handler_path("./target/debug/crashpad_handler")
.database_path("./dev_crashes")
.rate_limit(false) // Disable rate limiting for testing
.build()
} else {
// Production: with upload server
CrashpadConfig::builder()
.handler_path("/usr/local/bin/crashpad_handler")
.database_path("/var/crash/myapp")
.url("https://crashes.example.com/submit")
.upload_gzip(true) // Enable compression (default)
.build()
};// Control handler behavior with high-level API
let config = CrashpadConfig::builder()
.database_path("./crashes")
.rate_limit(false) // Disable upload rate limiting
.upload_gzip(false) // Disable gzip compression
.periodic_tasks(false) // Disable periodic maintenance
.identify_client_via_url(false) // Don't add client ID to URL
.build();
// Advanced: use low-level API for custom arguments
let config = CrashpadConfig::builder()
.database_path("./crashes")
.handler_argument("--monitor-self") // Enable self-monitoring
.handler_argument("--monitor-self-annotation=version=1.0")
.build();
// Mix high-level and low-level APIs
let config = CrashpadConfig::builder()
.database_path("./crashes")
.rate_limit(false) // High-level API
.handler_argument("--monitor-self") // Low-level API
.build();Note: Handler arguments are currently ignored on iOS/tvOS/watchOS as they use an in-process handler with hardcoded settings. This may change in future Crashpad versions.
| Platform | Architecture | Status | Handler Type |
|---|---|---|---|
| macOS | x86_64, aarch64 | ✅ Stable | External executable |
| Linux | x86_64, aarch64 | ✅ Stable | External executable |
| iOS | arm64, x86_64 sim | ✅ Stable | In-process |
| Android | arm, arm64, x86, x86_64 | ✅ Stable | External/In-process |
| Windows | x86_64 | ✅ Stable | External executable |
The dump_without_crash() method allows you to capture diagnostic information without terminating your application. This is useful for:
- Debugging production issues
- Capturing state during recoverable errors
- Performance monitoring
- User-requested diagnostics
use crashpad_rs::{CrashpadClient, CrashpadConfig};
// Initialize Crashpad as usual
let client = CrashpadClient::new()?;
let config = CrashpadConfig::builder()
.handler_path("./crashpad_handler")
.database_path("./crashes")
.build();
client.start_with_config(&config, &Default::default())?;
// Capture diagnostic dump on error condition
if let Err(e) = some_operation() {
// Log the error
eprintln!("Operation failed: {}", e);
// Capture current state for analysis
client.dump_without_crash();
// Continue running - no crash occurs
handle_error_gracefully(e);
}The test example automatically searches for the handler in common locations.
# Build and run directly
cargo run --example crashpad_test_cli
# The example will search for handler in:
# - target/debug/crashpad_handler (automatically found)
# - CRASHPAD_HANDLER environment variable (if set)
# - Current directory- Test the available commands
# Show help cargo run --example crashpad_test_cli -- --help # Capture a diagnostic dump without crashing cargo run --example crashpad_test_cli -- dump # Trigger a real crash for testing cargo run --example crashpad_test_cli -- crash # Run automated tests cargo run --example crashpad_test_cli -- test
The crashpad_handler executable must be available at runtime. There are two approaches:
Use crashpad-handler-bundler to automatically copy the handler at build time:
1. Add to your Cargo.toml:
[dependencies]
crashpad-rs = "x.y.z"
[build-dependencies]
crashpad-handler-bundler = "x.y.z"2. Create build.rs in your project root:
fn main() {
// Automatically copies handler to target directory
crashpad_handler_bundler::bundle().expect("Failed to bundle handler");
}3. Use in your application:
use crashpad_rs::{CrashpadClient, CrashpadConfig};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = CrashpadClient::new()?;
// Handler path is available via environment variable set by bundler
let handler_path = option_env!("CRASHPAD_HANDLER_PATH")
.unwrap_or("./crashpad_handler");
let config = CrashpadConfig::builder()
.handler_path(handler_path)
.database_path("./crashes")
.build();
client.start_with_config(&config, &Default::default())?;
Ok(())
}4. Build and run:
cargo build
# Output: cargo:warning=crashpad_handler copied to /path/to/target/debug/crashpad_handler
cargo run
# Handler is automatically availableThe bundler handles:
- Finding the built handler from crashpad-rs-sys
- Copying to the correct target directory
- Setting executable permissions on Unix
- Platform-specific naming (
.exeon Windows,.soon Android)
If not using the bundler, you need to manually deploy the handler:
-
Same directory as application (simplest)
my-app/ ├── my-app └── crashpad_handler -
System path (for installed applications)
/usr/local/bin/crashpad_handler -
Environment variable (flexible deployment)
export CRASHPAD_HANDLER=/opt/myapp/bin/crashpad_handler -
Bundled in package (platform-specific)
- macOS: Inside .app bundle
- Linux: In AppImage or snap
- Android: As .so file in APK (renamed to
libcrashpad_handler.so) - iOS: Not needed (in-process)
- API Documentation - Full API reference
- Integration Guide - Production integration
- Development Guide - Build, test, and contribute
- Architecture - Technical design decisions
- Conventions - Coding standards
- iOS Handler Arguments: Handler arguments are ignored on iOS/tvOS/watchOS as the in-process handler uses hardcoded settings (Crashpad limitation, see bug #23)
- Handler Update: No automatic update mechanism for deployed handlers
- Windows vendored build: The default
vendoredstrategy doesn't support Windows; usevendored-depotorprebuiltinstead
Contributions are welcome!
- Verify handler executable exists and has execute permissions
- Check
CRASHPAD_HANDLERenvironment variable - Explicitly set path in config:
.handler_path("/path/to/crashpad_handler") - Ensure handler architecture matches application
- Confirm handler process is running
- Check database path has write permissions
- Verify network connectivity for uploads
Licensed under MIT license (LICENSE).
Contributions are welcome! See DEVELOPING.md for build and test instructions.
- Issues: GitHub Issues
- Discussions: GitHub Discussions