From 0bc0c17f7b6bf61c183b24f2d6a2b5d63bfa6d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Mon, 24 Jul 2023 06:29:04 -0700 Subject: [PATCH] Add an example symbolizing a captured backtrace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 52d05139b395 ("Provide runnable example for symbolize module") added a doc test symbolizing a backtrace to the symbolize module, which helps to quickly illustrate API usage. With this change we add the same example code as a dedicated example inside the examples/ folder, where it can be run via `cargo run`. Signed-off-by: Daniel Müller --- examples/backtrace.rs | 61 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 examples/backtrace.rs diff --git a/examples/backtrace.rs b/examples/backtrace.rs new file mode 100644 index 000000000..39d5d645d --- /dev/null +++ b/examples/backtrace.rs @@ -0,0 +1,61 @@ +use blazesym::symbolize::Process; +use blazesym::symbolize::Source; +use blazesym::symbolize::SymbolizedResult; +use blazesym::symbolize::Symbolizer; +use blazesym::Addr; +use blazesym::Pid; +use std::cmp::min; +use std::mem::size_of; +use std::mem::transmute; +use std::ptr; + +fn main() { + assert_eq!(size_of::<*mut libc::c_void>(), size_of::()); + // Retrieve up to 64 stack frames of the calling thread. + const MAX_CNT: usize = 64; + + let mut bt_buf = [ptr::null_mut::(); MAX_CNT]; + let bt_cnt = unsafe { libc::backtrace(bt_buf.as_mut_ptr(), MAX_CNT as _) } as usize; + let bt = &bt_buf[0..min(bt_cnt, MAX_CNT)]; + let bt = unsafe { transmute::<&[*mut libc::c_void], &[Addr]>(bt) }; + + // Symbolize the addresses for the current process, as that's where + // they were captured. + let src = Source::Process(Process::new(Pid::Slf)); + let symbolizer = Symbolizer::new(); + + let bt_syms = symbolizer.symbolize(&src, bt).unwrap(); + for (addr, syms) in bt.iter().zip(bt_syms) { + match &syms[..] { + [] => println!("0x{addr:016x}: "), + [sym] => { + let SymbolizedResult { + symbol, + addr, + path, + line, + .. + } = sym; + println!( + "0x{addr:016x} {symbol} @ 0x{addr:x} {}:{line}", + path.display() + ); + } + syms => { + // One address may get several results. + println!("0x{addr:016x} ({} entries)", syms.len()); + + for sym in syms { + let SymbolizedResult { + symbol, + addr, + path, + line, + .. + } = sym; + println!(" {symbol} @ 0x{addr:016x} {}:{line}", path.display()); + } + } + } + } +}