A minimal prototype demonstrating how to use Rust's gimli and addr2line crates to parse DWARF debug information from ELF files, exposed via a C FFI interface.
.
├── dwarf_addr2line/ # Rust library (shared object)
│ ├── Cargo.toml
│ ├── src/
│ │ └── lib.rs # FFI implementation
│ └── target/release/
│ ├── libdwarf_addr2line.so (5.8 MB)
│ └── libdwarf_addr2line.a (15 MB)
├── dwarf_addr2line.h # C header file
├── test_addr2line.c # C application
├── CMakeLists.txt # Build configuration
└── sample.c # Test program with debug info
Dependencies:
addr2line0.21 - High-level DWARF address-to-line translationgimli0.28 - Low-level DWARF parser (zero-copy, lazy parsing)object0.32 - ELF/Mach-O/PE binary parser
API Functions:
DwarfContext* dwarf_context_new(const char* path);
int dwarf_find_location(DwarfContext* ctx, uint64_t address, DwarfLocation* location);
const char* dwarf_last_error(void);
void dwarf_context_free(DwarfContext* ctx);
void dwarf_free_string(char* s);A command-line tool that demonstrates the library usage:
./test_addr2line <elf_file> [address1] [address2] ...- Rust toolchain (tested with 1.75.0)
- CMake 3.14+
- GCC or Clang
- CARGO_HOME set to
/localdisk/juf/.cargo(for this environment)
- Build Rust library:
export CARGO_HOME=/localdisk/juf/.cargo
cd dwarf_addr2line
cargo build --release- Build C application:
cd ..
cmake -B build
cmake --build buildgcc -g -O0 -o sample sample.cnm sample | grep -E "(add|multiply|main)"Output:
0000000000001149 T add
0000000000001161 T multiply
0000000000001178 T main
./build/test_addr2line ./sample 0x1149 0x1161 0x1178Output:
DWARF addr2line Test Application
=================================
Binary: ./sample
Looking up address 0x1149 in ./sample
File: /localdisk/juf/try_gimli/sample.c
Line: 3
Column: 23
Looking up address 0x1161 in ./sample
File: /localdisk/juf/try_gimli/sample.c
Line: 7
Column: 28
Looking up address 0x1178 in ./sample
File: /localdisk/juf/try_gimli/sample.c
Line: 11
Column: 12
Done!
- Shared library (
.so): 5.8 MB - Static library (
.a): 15 MB
Both contain:
- Rust FFI code
- addr2line crate
- gimli crate (DWARF parser)
- object crate (binary parser)
- Rust standard library
✅ Zero-copy parsing - gimli doesn't copy the input data ✅ Lazy parsing - Only parses what's needed ✅ Cross-platform - Supports ELF, Mach-O, PE formats ✅ Thread-safe - Thread-local error handling ✅ C-compatible ABI - Easy integration with C/C++ projects
The application only needs:
libc.so.6(always present)libm.so.6(math library - always present)libpthread.so.0(threading - always present)libdl.so.2(dynamic loading - always present)
No Rust runtime or compiler needed at runtime!
The library uses thread-local storage for error messages:
DwarfContext* ctx = dwarf_context_new("invalid.elf");
if (!ctx) {
const char* error = dwarf_last_error();
fprintf(stderr, "Error: %s\n", error);
}- Context lifetime: User must call
dwarf_context_free() - String ownership: File paths in
DwarfLocationare leaked (simplified for prototype) - Production consideration: Would need better string lifetime management
- First lookup: Parses DWARF sections (10-50ms for typical binaries)
- Subsequent lookups: Fast (cached context)
- Memory: Holds entire binary in memory (can be optimized with mmap)
This prototype demonstrates the feasibility of adding DWARF addr2line support to the PTI SDK for GPU binary symbolication.
Potential integration points:
src/levelzero/ze_collector.h(populatesource_file_name_andsource_line_number_)- New utility class:
src/utils/gpu_dwarf_resolver.{h,cc} - Optional CMake feature:
PTI_ENABLE_DWARF_ADDR2LINE
- Better string management - Use string pool or arena allocator
- Inline function support -
find_frames()for inlined functions - Symbol caching - Cache frequently looked-up addresses
- Error recovery - Graceful handling of corrupted DWARF
- GPU binary support - Test with Intel GPU ELF binaries (
.spv,.bin) - Address translation - Map GPU virtual addresses to DWARF addresses
This prototype uses:
gimli- Apache-2.0 / MITaddr2line- Apache-2.0 / MITobject- Apache-2.0 / MIT
All dependencies are dual-licensed under Apache-2.0 and MIT.