rstack 0.3.3

Stack traces of remote processes
Documentation
pub use unwind_::Error;
use unwind_::{Accessors, AddressSpace, Byteorder, Cursor, PTraceState, PTraceStateRef, RegNum};

use crate::{Frame, Symbol, TraceOptions, TracedThread};

pub struct State(AddressSpace<PTraceStateRef>);

impl State {
    pub fn new(_: u32) -> Result<State, Error> {
        AddressSpace::new(Accessors::ptrace(), Byteorder::DEFAULT).map(State)
    }
}

impl TracedThread {
    pub fn dump_inner(
        &self,
        space: &mut State,
        options: &TraceOptions,
        frames: &mut Vec<Frame>,
    ) -> Result<(), Error> {
        let state = PTraceState::new(self.id)?;
        let mut cursor = Cursor::remote(&space.0, &state)?;

        loop {
            let ip = cursor.register(RegNum::IP)?;
            let is_signal = cursor.is_signal_frame()?;

            let mut symbol = None;
            if options.symbols {
                match (cursor.procedure_name(), cursor.procedure_info()) {
                    (Ok(ref name), Ok(ref info)) if info.start_ip() + name.offset() == ip => {
                        symbol = Some(Symbol {
                            name: name.name().to_string(),
                            offset: name.offset(),
                            address: info.start_ip(),
                            size: info.end_ip() - info.start_ip(),
                        });
                    }
                    _ => {}
                }
            }

            frames.push(Frame {
                ip,
                is_signal,
                symbol,
            });

            if !cursor.step()? {
                break;
            }
        }

        Ok(())
    }
}