diff options
Diffstat (limited to 'vendor/addr2line/examples/addr2line.rs')
-rw-r--r-- | vendor/addr2line/examples/addr2line.rs | 212 |
1 files changed, 101 insertions, 111 deletions
diff --git a/vendor/addr2line/examples/addr2line.rs b/vendor/addr2line/examples/addr2line.rs index 4b228a706..fa4d8e457 100644 --- a/vendor/addr2line/examples/addr2line.rs +++ b/vendor/addr2line/examples/addr2line.rs @@ -2,7 +2,7 @@ extern crate addr2line; extern crate clap; extern crate fallible_iterator; extern crate gimli; -extern crate memmap; +extern crate memmap2; extern crate object; extern crate typed_arena; @@ -11,18 +11,18 @@ use std::fs::File; use std::io::{BufRead, Lines, StdinLock, Write}; use std::path::Path; -use clap::{App, Arg, Values}; +use clap::{Arg, Command, Values}; use fallible_iterator::FallibleIterator; -use object::{Object, ObjectSection}; +use object::{Object, ObjectSection, SymbolMap, SymbolMapName}; use typed_arena::Arena; use addr2line::{Context, Location}; -fn parse_uint_from_hex_string(string: &str) -> u64 { +fn parse_uint_from_hex_string(string: &str) -> Option<u64> { if string.len() > 2 && string.starts_with("0x") { - u64::from_str_radix(&string[2..], 16).expect("Failed to parse address") + u64::from_str_radix(&string[2..], 16).ok() } else { - u64::from_str_radix(string, 16).expect("Failed to parse address") + u64::from_str_radix(string, 16).ok() } } @@ -32,9 +32,9 @@ enum Addrs<'a> { } impl<'a> Iterator for Addrs<'a> { - type Item = u64; + type Item = Option<u64>; - fn next(&mut self) -> Option<u64> { + fn next(&mut self) -> Option<Option<u64>> { let text = match *self { Addrs::Args(ref mut vals) => vals.next().map(Cow::from), Addrs::Stdin(ref mut lines) => lines.next().map(Result::unwrap).map(Cow::from), @@ -45,15 +45,18 @@ impl<'a> Iterator for Addrs<'a> { } } -fn print_loc(loc: &Option<Location>, basenames: bool, llvm: bool) { - if let Some(ref loc) = *loc { - let file = loc.file.as_ref().unwrap(); - let path = if basenames { - Path::new(Path::new(file).file_name().unwrap()) +fn print_loc(loc: Option<&Location>, basenames: bool, llvm: bool) { + if let Some(ref loc) = loc { + if let Some(ref file) = loc.file.as_ref() { + let path = if basenames { + Path::new(Path::new(file).file_name().unwrap()) + } else { + Path::new(file) + }; + print!("{}:", path.display()); } else { - Path::new(file) - }; - print!("{}:", path.display()); + print!("??:"); + } if llvm { print!("{}:{}", loc.line.unwrap_or(0), loc.column.unwrap_or(0)); } else if let Some(line) = loc.line { @@ -65,15 +68,19 @@ fn print_loc(loc: &Option<Location>, basenames: bool, llvm: bool) { } else if llvm { println!("??:0:0"); } else { - println!("??:?"); + println!("??:0"); } } -fn print_function(name: &str, language: Option<gimli::DwLang>, demangle: bool) { - if demangle { - print!("{}", addr2line::demangle_auto(Cow::from(name), language)); +fn print_function(name: Option<&str>, language: Option<gimli::DwLang>, demangle: bool) { + if let Some(name) = name { + if demangle { + print!("{}", addr2line::demangle_auto(Cow::from(name), language)); + } else { + print!("{}", name); + } } else { - print!("{}", name); + print!("??"); } } @@ -94,77 +101,61 @@ fn load_file_section<'input, 'arena, Endian: gimli::Endianity>( } } +fn find_name_from_symbols<'a>( + symbols: &'a SymbolMap<SymbolMapName>, + probe: u64, +) -> Option<&'a str> { + symbols.get(probe).map(|x| x.name()) +} + fn main() { - let matches = App::new("hardliner") + let matches = Command::new("addr2line") .version("0.1") - .about("A fast addr2line clone") - .arg( - Arg::with_name("exe") - .short("e") + .about("A fast addr2line Rust port") + .args(&[ + Arg::new("exe") + .short('e') .long("exe") .value_name("filename") .help( "Specify the name of the executable for which addresses should be translated.", ) .required(true), - ) - .arg( - Arg::with_name("sup") + Arg::new("sup") .long("sup") .value_name("filename") .help("Path to supplementary object file."), - ) - .arg( - Arg::with_name("functions") - .short("f") + Arg::new("functions") + .short('f') .long("functions") .help("Display function names as well as file and line number information."), - ) - .arg( - Arg::with_name("pretty") - .short("p") - .long("pretty-print") - .help( - "Make the output more human friendly: each location are printed on \ - one line.", - ), - ) - .arg(Arg::with_name("inlines").short("i").long("inlines").help( - "If the address belongs to a function that was inlined, the source \ - information for all enclosing scopes back to the first non-inlined \ - function will also be printed.", - )) - .arg( - Arg::with_name("addresses") - .short("a") - .long("addresses") - .help( - "Display the address before the function name, file and line \ - number information.", - ), - ) - .arg( - Arg::with_name("basenames") - .short("s") + Arg::new("pretty").short('p').long("pretty-print").help( + "Make the output more human friendly: each location are printed on one line.", + ), + Arg::new("inlines").short('i').long("inlines").help( + "If the address belongs to a function that was inlined, the source information for \ + all enclosing scopes back to the first non-inlined function will also be printed.", + ), + Arg::new("addresses").short('a').long("addresses").help( + "Display the address before the function name, file and line number information.", + ), + Arg::new("basenames") + .short('s') .long("basenames") .help("Display only the base of each file name."), - ) - .arg(Arg::with_name("demangle").short("C").long("demangle").help( - "Demangle function names. \ - Specifying a specific demangling style (like GNU addr2line) \ - is not supported. (TODO)", - )) - .arg( - Arg::with_name("llvm") + Arg::new("demangle").short('C').long("demangle").help( + "Demangle function names. \ + Specifying a specific demangling style (like GNU addr2line) is not supported. \ + (TODO)" + ), + Arg::new("llvm") .long("llvm") .help("Display output in the same format as llvm-symbolizer."), - ) - .arg( - Arg::with_name("addrs") + Arg::new("addrs") .takes_value(true) - .multiple(true) + .multiple_occurrences(true) .help("Addresses to use instead of reading from stdin."), - ) + ]) .get_matches(); let arena_data = Arena::new(); @@ -179,7 +170,7 @@ fn main() { let path = matches.value_of("exe").unwrap(); let file = File::open(path).unwrap(); - let map = unsafe { memmap::Mmap::map(&file).unwrap() }; + let map = unsafe { memmap2::Mmap::map(&file).unwrap() }; let object = &object::File::parse(&*map).unwrap(); let endian = if object.is_little_endian() { @@ -195,7 +186,7 @@ fn main() { let sup_map; let sup_object = if let Some(sup_path) = matches.value_of("sup") { let sup_file = File::open(sup_path).unwrap(); - sup_map = unsafe { memmap::Mmap::map(&sup_file).unwrap() }; + sup_map = unsafe { memmap2::Mmap::map(&sup_file).unwrap() }; Some(object::File::parse(&*sup_map).unwrap()) } else { None @@ -220,10 +211,11 @@ fn main() { for probe in addrs { if print_addrs { + let addr = probe.unwrap_or(0); if llvm { - print!("0x{:x}", probe); + print!("0x{:x}", addr); } else { - print!("0x{:016x}", probe); + print!("0x{:016x}", addr); } if pretty { print!(": "); @@ -234,44 +226,46 @@ fn main() { if do_functions || do_inlines { let mut printed_anything = false; - let mut frames = ctx.find_frames(probe).unwrap().enumerate(); - while let Some((i, frame)) = frames.next().unwrap() { - if pretty && i != 0 { - print!(" (inlined by) "); - } - - if do_functions { - if let Some(func) = frame.function { - print_function(&func.raw_name().unwrap(), func.language, demangle); - } else if let Some(name) = symbols.get(probe).map(|x| x.name()) { - print_function(name, None, demangle); - } else { - print!("??"); + if let Some(probe) = probe { + let mut frames = ctx.find_frames(probe).unwrap().enumerate(); + while let Some((i, frame)) = frames.next().unwrap() { + if pretty && i != 0 { + print!(" (inlined by) "); } - if pretty { - print!(" at "); - } else { - println!(); + if do_functions { + if let Some(func) = frame.function { + print_function( + func.raw_name().ok().as_ref().map(AsRef::as_ref), + func.language, + demangle, + ); + } else { + let name = find_name_from_symbols(&symbols, probe); + print_function(name, None, demangle); + } + + if pretty { + print!(" at "); + } else { + println!(); + } } - } - print_loc(&frame.location, basenames, llvm); + print_loc(frame.location.as_ref(), basenames, llvm); - printed_anything = true; + printed_anything = true; - if !do_inlines { - break; + if !do_inlines { + break; + } } } if !printed_anything { if do_functions { - if let Some(name) = symbols.get(probe).map(|x| x.name()) { - print_function(name, None, demangle); - } else { - print!("??"); - } + let name = probe.and_then(|probe| find_name_from_symbols(&symbols, probe)); + print_function(name, None, demangle); if pretty { print!(" at "); @@ -280,15 +274,11 @@ fn main() { } } - if llvm { - println!("??:0:0"); - } else { - println!("??:?"); - } + print_loc(None, basenames, llvm); } } else { - let loc = ctx.find_location(probe).unwrap(); - print_loc(&loc, basenames, llvm); + let loc = probe.and_then(|probe| ctx.find_location(probe).unwrap()); + print_loc(loc.as_ref(), basenames, llvm); } if llvm { |