diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
commit | dc0db358abe19481e475e10c32149b53370f1a1c (patch) | |
tree | ab8ce99c4b255ce46f99ef402c27916055b899ee /vendor/addr2line/examples | |
parent | Releasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/addr2line/examples')
-rw-r--r-- | vendor/addr2line/examples/addr2line.rs | 128 |
1 files changed, 78 insertions, 50 deletions
diff --git a/vendor/addr2line/examples/addr2line.rs b/vendor/addr2line/examples/addr2line.rs index fa4d8e457..97fc80222 100644 --- a/vendor/addr2line/examples/addr2line.rs +++ b/vendor/addr2line/examples/addr2line.rs @@ -1,17 +1,9 @@ -extern crate addr2line; -extern crate clap; -extern crate fallible_iterator; -extern crate gimli; -extern crate memmap2; -extern crate object; -extern crate typed_arena; - use std::borrow::Cow; use std::fs::File; use std::io::{BufRead, Lines, StdinLock, Write}; -use std::path::Path; +use std::path::{Path, PathBuf}; -use clap::{Arg, Command, Values}; +use clap::{Arg, ArgAction, Command}; use fallible_iterator::FallibleIterator; use object::{Object, ObjectSection, SymbolMap, SymbolMapName}; use typed_arena::Arena; @@ -27,7 +19,7 @@ fn parse_uint_from_hex_string(string: &str) -> Option<u64> { } enum Addrs<'a> { - Args(Values<'a>), + Args(clap::parser::ValuesRef<'a, String>), Stdin(Lines<StdinLock<'a>>), } @@ -45,8 +37,8 @@ impl<'a> Iterator for Addrs<'a> { } } -fn print_loc(loc: Option<&Location>, basenames: bool, llvm: bool) { - if let Some(ref loc) = loc { +fn print_loc(loc: Option<&Location<'_>>, basenames: bool, llvm: bool) { + if let Some(loc) = loc { if let Some(ref file) = loc.file.as_ref() { let path = if basenames { Path::new(Path::new(file).file_name().unwrap()) @@ -102,21 +94,35 @@ fn load_file_section<'input, 'arena, Endian: gimli::Endianity>( } fn find_name_from_symbols<'a>( - symbols: &'a SymbolMap<SymbolMapName>, + symbols: &'a SymbolMap<SymbolMapName<'_>>, probe: u64, ) -> Option<&'a str> { symbols.get(probe).map(|x| x.name()) } +struct Options<'a> { + do_functions: bool, + do_inlines: bool, + pretty: bool, + print_addrs: bool, + basenames: bool, + demangle: bool, + llvm: bool, + exe: &'a PathBuf, + sup: Option<&'a PathBuf>, +} + fn main() { let matches = Command::new("addr2line") - .version("0.1") + .version(env!("CARGO_PKG_VERSION")) .about("A fast addr2line Rust port") + .max_term_width(100) .args(&[ Arg::new("exe") .short('e') .long("exe") .value_name("filename") + .value_parser(clap::value_parser!(PathBuf)) .help( "Specify the name of the executable for which addresses should be translated.", ) @@ -124,52 +130,66 @@ fn main() { Arg::new("sup") .long("sup") .value_name("filename") + .value_parser(clap::value_parser!(PathBuf)) .help("Path to supplementary object file."), Arg::new("functions") .short('f') .long("functions") + .action(ArgAction::SetTrue) .help("Display function names as well as file and line number information."), - Arg::new("pretty").short('p').long("pretty-print").help( + Arg::new("pretty").short('p').long("pretty-print") + .action(ArgAction::SetTrue) + .help( "Make the output more human friendly: each location are printed on one line.", ), - Arg::new("inlines").short('i').long("inlines").help( + Arg::new("inlines").short('i').long("inlines") + .action(ArgAction::SetTrue) + .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( + Arg::new("addresses").short('a').long("addresses") + .action(ArgAction::SetTrue) + .help( "Display the address before the function name, file and line number information.", ), Arg::new("basenames") .short('s') .long("basenames") + .action(ArgAction::SetTrue) .help("Display only the base of each file name."), - Arg::new("demangle").short('C').long("demangle").help( + Arg::new("demangle").short('C').long("demangle") + .action(ArgAction::SetTrue) + .help( "Demangle function names. \ Specifying a specific demangling style (like GNU addr2line) is not supported. \ (TODO)" ), Arg::new("llvm") .long("llvm") + .action(ArgAction::SetTrue) .help("Display output in the same format as llvm-symbolizer."), Arg::new("addrs") - .takes_value(true) - .multiple_occurrences(true) + .action(ArgAction::Append) .help("Addresses to use instead of reading from stdin."), ]) .get_matches(); let arena_data = Arena::new(); - let do_functions = matches.is_present("functions"); - let do_inlines = matches.is_present("inlines"); - let pretty = matches.is_present("pretty"); - let print_addrs = matches.is_present("addresses"); - let basenames = matches.is_present("basenames"); - let demangle = matches.is_present("demangle"); - let llvm = matches.is_present("llvm"); - let path = matches.value_of("exe").unwrap(); + let opts = Options { + do_functions: matches.get_flag("functions"), + do_inlines: matches.get_flag("inlines"), + pretty: matches.get_flag("pretty"), + print_addrs: matches.get_flag("addresses"), + basenames: matches.get_flag("basenames"), + demangle: matches.get_flag("demangle"), + llvm: matches.get_flag("llvm"), + exe: matches.get_one::<PathBuf>("exe").unwrap(), + sup: matches.get_one::<PathBuf>("sup"), + }; - let file = File::open(path).unwrap(); + let file = File::open(opts.exe).unwrap(); let map = unsafe { memmap2::Mmap::map(&file).unwrap() }; let object = &object::File::parse(&*map).unwrap(); @@ -184,7 +204,7 @@ fn main() { }; let sup_map; - let sup_object = if let Some(sup_path) = matches.value_of("sup") { + let sup_object = if let Some(sup_path) = opts.sup { let sup_file = File::open(sup_path).unwrap(); sup_map = unsafe { memmap2::Mmap::map(&sup_file).unwrap() }; Some(object::File::parse(&*sup_map).unwrap()) @@ -201,87 +221,95 @@ fn main() { dwarf.load_sup(&mut load_sup_section).unwrap(); } + let mut split_dwarf_loader = addr2line::builtin_split_dwarf_loader::SplitDwarfLoader::new( + |data, endian| { + gimli::EndianSlice::new(arena_data.alloc(Cow::Owned(data.into_owned())), endian) + }, + Some(opts.exe.clone()), + ); let ctx = Context::from_dwarf(dwarf).unwrap(); let stdin = std::io::stdin(); let addrs = matches - .values_of("addrs") + .get_many::<String>("addrs") .map(Addrs::Args) .unwrap_or_else(|| Addrs::Stdin(stdin.lock().lines())); for probe in addrs { - if print_addrs { + if opts.print_addrs { let addr = probe.unwrap_or(0); - if llvm { + if opts.llvm { print!("0x{:x}", addr); } else { print!("0x{:016x}", addr); } - if pretty { + if opts.pretty { print!(": "); } else { println!(); } } - if do_functions || do_inlines { + if opts.do_functions || opts.do_inlines { let mut printed_anything = false; if let Some(probe) = probe { - let mut frames = ctx.find_frames(probe).unwrap().enumerate(); + let frames = ctx.find_frames(probe); + let frames = split_dwarf_loader.run(frames).unwrap(); + let mut frames = frames.enumerate(); while let Some((i, frame)) = frames.next().unwrap() { - if pretty && i != 0 { + if opts.pretty && i != 0 { print!(" (inlined by) "); } - if do_functions { + if opts.do_functions { if let Some(func) = frame.function { print_function( func.raw_name().ok().as_ref().map(AsRef::as_ref), func.language, - demangle, + opts.demangle, ); } else { let name = find_name_from_symbols(&symbols, probe); - print_function(name, None, demangle); + print_function(name, None, opts.demangle); } - if pretty { + if opts.pretty { print!(" at "); } else { println!(); } } - print_loc(frame.location.as_ref(), basenames, llvm); + print_loc(frame.location.as_ref(), opts.basenames, opts.llvm); printed_anything = true; - if !do_inlines { + if !opts.do_inlines { break; } } } if !printed_anything { - if do_functions { + if opts.do_functions { let name = probe.and_then(|probe| find_name_from_symbols(&symbols, probe)); - print_function(name, None, demangle); + print_function(name, None, opts.demangle); - if pretty { + if opts.pretty { print!(" at "); } else { println!(); } } - print_loc(None, basenames, llvm); + print_loc(None, opts.basenames, opts.llvm); } } else { let loc = probe.and_then(|probe| ctx.find_location(probe).unwrap()); - print_loc(loc.as_ref(), basenames, llvm); + print_loc(loc.as_ref(), opts.basenames, opts.llvm); } - if llvm { + if opts.llvm { println!(); } std::io::stdout().flush().unwrap(); |