15 breaking releases

0.16.1 Aug 29, 2018
0.16.0 Jun 1, 2018
0.15.0 Dec 1, 2017
0.14.0 Aug 8, 2017
0.3.0 Jul 27, 2016

#16 in Parser implementations

Download history 641/week @ 2018-09-10 389/week @ 2018-09-17 407/week @ 2018-09-24 454/week @ 2018-10-01 528/week @ 2018-10-08 485/week @ 2018-10-15 554/week @ 2018-10-22 409/week @ 2018-10-29 407/week @ 2018-11-05 656/week @ 2018-11-12 860/week @ 2018-11-19 595/week @ 2018-11-26 604/week @ 2018-12-03

2,317 downloads per month
Used in 16 crates (13 directly)


20K SLoC


gimli is a blazing fast library for consuming the DWARF debugging format.

Example Usage

Print out all of the functions in the debuggee program:

extern crate gimli;

# fn example() -> Result<(), gimli::Error> {
# let debug_info_buf = [];
# let debug_abbrev_buf = [];
# let read_debug_info = || &debug_info_buf;
# let read_debug_abbrev = || &debug_abbrev_buf;
// Read the .debug_info and .debug_abbrev sections with whatever object
// loader you're using.
let endian = gimli::LittleEndian;
let debug_info = gimli::DebugInfo::new(read_debug_info(), endian);
let debug_abbrev = gimli::DebugAbbrev::new(read_debug_abbrev(), endian);

// Iterate over all compilation units.
let mut iter = debug_info.units();
while let Some(unit) = try!(iter.next()) {
    // Parse the abbreviations for this compilation unit.
    let abbrevs = try!(unit.abbreviations(&debug_abbrev));

    // Iterate over all of this compilation unit's entries.
    let mut entries = unit.entries(&abbrevs);
    while let Some((_, entry)) = try!(entries.next_dfs()) {
        // If we find an entry for a function, print it.
        if entry.tag() == gimli::DW_TAG_subprogram {
            println!("Found a function: {:?}", entry);
# unreachable!()
# }

Full example programs:

  • A dwarfdump clone

  • An addr2line clone

  • ddbug, a utility giving insight into code generation by making debugging information readable

  • dwprod, a tiny utility to list the compilers used to create each compilation unit within a shared library or executable (via DW_AT_producer)

  • dwarf-validate, a program to validate the integrity of some DWARF and its references between sections and ocmpilation units.

API Structure

  • Basic familiarity with DWARF is assumed.

  • Each section gets its own type. Consider these types the entry points to the library:

  • Each section type exposes methods for accessing the debugging data encoded in that section. For example, the DebugInfo struct has the units method for iterating over the compilation units defined within it.

  • Offsets into a section are strongly typed: an offset into .debug_info is the DebugInfoOffset type. It cannot be used to index into the DebugLine type because DebugLine represents the .debug_line section. There are similar types for offsets relative to a compilation unit rather than a section.

Using with FallibleIterator

The standard library's Iterator trait and related APIs do not play well with iterators where the next operation is fallible. One can make the Iterator's associated Item type be a Result<T, E>, however the provided methods cannot gracefully handle the case when an Err is returned.

This situation led to the fallible-iterator crate's existence. You can read more of the rationale for its existence in its docs. The crate provides the helpers you have come to expect (eg map, filter, etc) for iterators that can fail.

gimli's many lazy parsing iterators are a perfect match for the fallible-iterator crate's FallibleIterator trait because parsing is not done eagerly. Parse errors later in the input might only be discovered after having iterated through many items.

To use gimli iterators with FallibleIterator, import the crate and trait into your code:

// Add the `fallible-iterator` crate. Don't forget to add it to your
// `Cargo.toml`, too!
extern crate fallible_iterator;
extern crate gimli;

// Use the `FallibleIterator` trait so its methods are in scope!
use fallible_iterator::FallibleIterator;
use gimli::{DebugAranges, EndianBuf, LittleEndian};

fn find_sum_of_address_range_lengths(aranges: DebugAranges<EndianBuf<LittleEndian>>)
    -> gimli::Result<u64>
    // `DebugAranges::items` returns a `FallibleIterator`!
        // `map` is provided by `FallibleIterator`!
        .map(|arange| arange.length())
        // `fold` is provided by `FallibleIterator`!
        .fold(0, |sum, len| sum + len)

# fn main() {}

Cargo Features

Cargo features that can be enabled with gimli:

  • std: Enabled by default. Use the std library. Disabling this feature allows using gimli in embedded environments that do not have access to std. Note that even when std is disabled, gimli still requires an implementation of the alloc crate, and you must enable the nightly feature.

  • alloc: Nightly only. Enables usage of the unstable, nightly-only #![feature(alloc)] Rust feature that allows gimli to use boxes and collection types in a #[no_std] environment.