Struct addr2line::Context

source ·
pub struct Context<R: Reader> {
    pub(crate) sections: Arc<Dwarf<R>>,
    pub(crate) unit_ranges: Box<[UnitRange]>,
    pub(crate) units: Box<[ResUnit<R>]>,
    pub(crate) sup_units: Box<[SupUnit<R>]>,
}
Expand description

The state necessary to perform address to line translation.

Constructing a Context is somewhat costly, so users should aim to reuse Contexts when performing lookups for many addresses in the same executable.

Fields§

§sections: Arc<Dwarf<R>>§unit_ranges: Box<[UnitRange]>§units: Box<[ResUnit<R>]>§sup_units: Box<[SupUnit<R>]>

Implementations§

source§

impl<R: Reader> Context<R>

source

pub fn from_sections( debug_abbrev: DebugAbbrev<R>, debug_addr: DebugAddr<R>, debug_aranges: DebugAranges<R>, debug_info: DebugInfo<R>, debug_line: DebugLine<R>, debug_line_str: DebugLineStr<R>, debug_ranges: DebugRanges<R>, debug_rnglists: DebugRngLists<R>, debug_str: DebugStr<R>, debug_str_offsets: DebugStrOffsets<R>, default_section: R ) -> Result<Self, Error>

Construct a new Context from DWARF sections.

This method does not support using a supplementary object file.

source

pub fn from_dwarf(sections: Dwarf<R>) -> Result<Context<R>, Error>

Construct a new Context from an existing gimli::Dwarf object.

source

pub(crate) fn find_units(&self, probe: u64) -> impl Iterator<Item = &ResUnit<R>>

Finds the CUs for the function address given.

There might be multiple CUs whose range contains this address. Weak symbols have shown up in the wild which cause this to happen but otherwise this can happen if the CU has non-contiguous functions but only reports a single range.

Consequently we return an iterator for all CUs which may contain the address, and the caller must check if there is actually a function or location in the CU for that address.

source

pub(crate) fn find_units_range( &self, probe_low: u64, probe_high: u64 ) -> impl Iterator<Item = (&ResUnit<R>, &Range)>

Finds the CUs covering the range of addresses given.

The range is [low, high) (ie, the upper bound is exclusive). This can return multiple ranges for the same unit.

source

pub fn find_dwarf_and_unit( &self, probe: u64 ) -> LookupResult<impl LookupContinuation<Output = Option<(&Dwarf<R>, &Unit<R>)>, Buf = R>>

Find the DWARF unit corresponding to the given virtual memory address.

source

pub fn find_location(&self, probe: u64) -> Result<Option<Location<'_>>, Error>

Find the source file and line corresponding to the given virtual memory address.

source

pub fn find_location_range( &self, probe_low: u64, probe_high: u64 ) -> Result<LocationRangeIter<'_, R>, Error>

Return source file and lines for a range of addresses. For each location it also returns the address and size of the range of the underlying instructions.

source

pub fn find_frames( &self, probe: u64 ) -> LookupResult<impl LookupContinuation<Output = Result<FrameIter<'_, R>, Error>, Buf = R>>

Return an iterator for the function frames corresponding to the given virtual memory address.

If the probe address is not for an inline function then only one frame is returned.

If the probe address is for an inline function then the first frame corresponds to the innermost inline function. Subsequent frames contain the caller and call location, until an non-inline caller is reached.

source

pub fn preload_units( &self, probe: u64 ) -> impl Iterator<Item = (SplitDwarfLoad<R>, impl FnOnce(Option<Arc<Dwarf<R>>>) -> Result<(), Error> + '_)>

Preload units for probe.

The iterator returns pairs of SplitDwarfLoads containing the information needed to locate and load split DWARF for probe and a matching callback to invoke once that data is available.

If this method is called, and all of the returned closures are invoked, addr2line guarantees that any future API call for the address probe will not require the loading of any split DWARF.

  const ADDRESS: u64 = 0xdeadbeef;
  ctx.preload_units(ADDRESS).for_each(|(load, callback)| {
    let dwo = do_split_dwarf_load(load);
    callback(dwo);
  });

  let frames_iter = match ctx.find_frames(ADDRESS) {
    LookupResult::Output(result) => result,
    LookupResult::Load { .. } => unreachable!("addr2line promised we wouldn't get here"),
  };

  // ...
source§

impl<R: Reader> Context<R>

source

pub(crate) fn parse_units( sections: &Dwarf<R> ) -> Result<(Vec<UnitRange>, Vec<ResUnit<R>>), Error>

source

pub(crate) fn parse_sup(sections: &Dwarf<R>) -> Result<Vec<SupUnit<R>>, Error>

source

pub(crate) fn find_unit( &self, offset: DebugInfoOffset<R::Offset>, file: DebugFile ) -> Result<(&Unit<R>, UnitOffset<R::Offset>), Error>

Auto Trait Implementations§

§

impl<R> !RefUnwindSafe for Context<R>

§

impl<R> Send for Context<R>where R: Send + Sync, <R as Reader>::Offset: Send,

§

impl<R> !Sync for Context<R>

§

impl<R> Unpin for Context<R>

§

impl<R> UnwindSafe for Context<R>where R: UnwindSafe + RefUnwindSafe, <R as Reader>::Offset: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.