Symbolic
A Rust crate suite that symbolicates native stack traces, minidumps, and JS sourcemaps for crash reporting pipelines.
Repository Health
Technical Analysis
Symbolic is a Rust workspace of largely independent crates built and maintained by Sentry to turn raw crash data into readable stack traces. It parses debug information from Mach-O, ELF, PE, PDB, Portable PDB, and Breakpad symbol files, builds a compact platform-independent symcache for fast address-to-function-and-line lookups, extracts call frame information for stack unwinding, demangles C++/Rust/Swift/Objective-C symbols, and expands minified JavaScript stack traces against sourcemaps.
Beyond native symbolication, the crate also processes Unreal Engine 4 crash archives (extracting minidumps, logs, and context) and generates Breakpad-format symbol files from Mach-O, ELF, and PDB inputs. Everything is exposed through a feature-flagged umbrella crate for Rust consumers, plus a C ABI (symbolic-cabi) and a Python package with prebuilt wheels, so the same symbolication logic that powers Sentry’s crash-report pipeline can be embedded in tools written in other languages.
What You Get
- Object-file parsing for Mach-O, ELF, PE, PDB, Portable PDB, and Breakpad symbol formats behind a unified Object/ObjectLike interface
- A compact, versioned symcache binary format for fast address-to-function-and-line symbolication lookups
- Call frame information (CFI) extraction for native stack unwinding
- Demangling for C++ (GCC/Clang/MSVC), Rust, Swift, and Objective-C/C++ symbols
- JavaScript sourcemap expansion with heuristics to recover original function names from minified sources
- Unreal Engine 4 crash report processing, including minidump extraction and log/context parsing
- Breakpad symbol file generation from Mach-O, ELF, and PDB debug data
- A C ABI crate and Python package (with prebuilt Linux/macOS wheels) for non-Rust consumers
Common Use Cases
- Crash reporting backends - services that ingest native crash dumps or minified JS stack traces and need to resolve them to human-readable function names and source locations
- Symbol server tooling - building or extending infrastructure that converts uploaded debug files into symcaches for fast symbolication at scale
- Unreal Engine crash pipelines - extracting and interpreting UE4 crash archives (minidumps, logs, engine context) in a backend service
- Cross-language crash tooling - embedding Sentry-grade symbolication in Python or C/C++ tooling via the bundled Python wheel or C ABI instead of reimplementing debug-format parsing
- Source bundle / sourcemap tooling - generating source archives and resolving minified JS locations back to original files, similar to what sentry-cli’s difutil bundle-sources does internally
Under The Hood
Architecture
Symbolic is a Cargo workspace of ~11 largely independent crates unified behind one umbrella symbolic crate that re-exports each subsystem gated by Cargo features (cfi, debuginfo, demangle, il2cpp, ppdb, sourcemapcache, symcache, unreal). symbolic-common provides shared primitives (ByteView, CPU/architecture types, path and source-link heuristics) used throughout. symbolic-debuginfo unifies Mach-O, ELF, PE, PDB, Portable PDB, Breakpad, and WASM object formats behind a common Object/ObjectLike trait, with each format isolated in its own submodule (macho/, dwarf/, pdb/, wasm/). symbolic-symcache converts parsed debug info into a compact, versioned binary cache (raw.rs, writer.rs, a v9/ format module) optimized for lookup speed rather than parse speed, and symbolic-cabi flattens the whole surface into a C ABI consumed by the bundled Python package. This design means adding support for a new debug format only touches its own submodule, but a change to the core Object trait or the symcache binary layout ripples through every downstream crate and the C ABI.
Tech Stack
Built on Rust 2024 edition with an MSRV of 1.85. Debug-format parsing leans on gimli (DWARF) and goblin (Mach-O/ELF/PE), Windows symbols on pdb/pdb-addr2line, and minidump handling on the minidump/minidump-processor/minidump-unwind crates. JavaScript support comes from sourcemap and js-source-scopes, Android mapping from proguard, and demangling from rustc-demangle and cpp_demangle. Compression is handled via zip, zstd, and flate2, and the binary cache format is written with Sentry’s own watto crate. A separate symbolic-wasm crate builds a WebAssembly target via wasm-bindgen, and py/ contains a Python extension package built from the C ABI, with criterion for benchmarks and insta for snapshot testing.
Code Quality
Over 50 files across the workspace contain Rust unit tests, spanning breakpad, debuginfo, demangle, sourcemapcache, ppdb, symcache, cfi, and unreal crates, supplemented by insta snapshot tests and a separate Python pytest suite under py/tests. CI enforces cargo fmt --check, cargo clippy --all-features --workspace --tests --examples -D clippy::all, and a dedicated doc-comments job that builds with RUSTDOCFLAGS=-Dwarnings against #![warn(missing_docs)], so undocumented public items fail the build. Errors are modeled with typed thiserror-based enums per subcrate rather than panics or string errors. Tests run across a Linux/macOS/Windows matrix, reflecting the format-parsing code’s platform sensitivity.
API Design
The umbrella crate’s Cargo feature flags let consumers pull in only the debug-format and processing support they need, keeping default builds lean while still exposing symbolic::debuginfo, symbolic::symcache, symbolic::demangle, and similar modules that mirror the underlying crate names for predictability. The symcache format itself is versioned and documented in its own module (v9/), and the same functionality is mirrored through a C ABI and a Python package with prebuilt wheels, giving non-Rust consumers a first-class path in rather than requiring them to reimplement debug-format parsing. Getting started for basic symbolication needs only the default feature set; more advanced workflows (CFI, Unreal parsing, IL2CPP) require explicit opt-in research into which feature unlocks which subsystem.