pub trait SymbolProvider {
    // Required methods
    fn fill_symbol<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        module: &'life1 (dyn Module + Sync),
        frame: &'life2 mut (dyn FrameSymbolizer + Send)
    ) -> Pin<Box<dyn Future<Output = Result<(), FillSymbolError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn walk_frame<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        module: &'life1 (dyn Module + Sync),
        walker: &'life2 mut (dyn FrameWalker + Send)
    ) -> Pin<Box<dyn Future<Output = Option<()>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn get_file_path<'life0, 'life1, 'async_trait>(
        &'life0 self,
        module: &'life1 (dyn Module + Sync),
        file_kind: FileKind
    ) -> Pin<Box<dyn Future<Output = Result<PathBuf, FileError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;

    // Provided methods
    fn stats(&self) -> HashMap<String, SymbolStats> { ... }
    fn pending_stats(&self) -> PendingSymbolStats { ... }
}
Expand description

The SymbolProvider is the main extension point for minidump processing.

It is primarily used by the process_minidump function to do stack unwinding via CFI (call frame information) of a Module using the walk_frame function.

The fill_symbol function is responsible for filling in the source location (function, file, line triple) corresponding to an instruction address, as well as a dual purpose of informing the stack scanning heuristic whether a given instruction address might be valid inside of a Module.

All the asynchronous trait methods can be called concurrently and need to handle synchronization and request coalescing (based on the Module).

Required Methods§

source

fn fill_symbol<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, module: &'life1 (dyn Module + Sync), frame: &'life2 mut (dyn FrameSymbolizer + Send) ) -> Pin<Box<dyn Future<Output = Result<(), FillSymbolError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Fill symbol information in FrameSymbolizer using the instruction address from frame, and the module information from Module.

An Error indicates that no symbols could be found for the relevant module.

This is used for filling in the resulting source location of the frame as a (function, file, line) triple, as well as providing the parameter_size which is used during CFI evaluation and stack walking.

This function also serves a dual purpose in informing the stack scanning heuristic whether a potential instruction address points to a valid function or not.

source

fn walk_frame<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, module: &'life1 (dyn Module + Sync), walker: &'life2 mut (dyn FrameWalker + Send) ) -> Pin<Box<dyn Future<Output = Option<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Tries to use CFI to walk the stack frame of the FrameWalker using the symbols of the given Module.

Output should be written using the FrameWalker’s set_caller_* APIs.

source

fn get_file_path<'life0, 'life1, 'async_trait>( &'life0 self, module: &'life1 (dyn Module + Sync), file_kind: FileKind ) -> Pin<Box<dyn Future<Output = Result<PathBuf, FileError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Gets the path to the binary code file for a given module (or an Error).

This might be used later on to inspect the assembly instructions of a module.

Provided Methods§

source

fn stats(&self) -> HashMap<String, SymbolStats>

Collect various statistics on the symbols.

Keys are implementation dependent. For example the file name of the module (code_file’s file name).

This is only really intended to be queried after processing an entire minidump, and may have non-trivial overhead to compute. It’s als possible we’d want it to also be able to contain stats that don’t really make sense in intermediate states.

In a world where you might want to have one SymbolSupplier shared by multiple instances of process running in parallel, it’s unclear if this is the right abstraction. Perhaps we should have some kind of “session” abstraction so you can get stats about each individual processing task? Of course all pooling/caching between the tasks muddies things too.

source

fn pending_stats(&self) -> PendingSymbolStats

Collect various pending statistics on the symbols.

This is intended to be queried during processing to give some interactive feedback to the user, and so is fine to poll as much as you want, whenever you want.

Implementors§