summaryrefslogtreecommitdiffstats
path: root/vendor/addr2line/examples/addr2line.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/addr2line/examples/addr2line.rs')
-rw-r--r--vendor/addr2line/examples/addr2line.rs212
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 {