Skip to content
This repository has been archived by the owner on Jan 30, 2024. It is now read-only.

Include program counter value in backtrace when -v is passed #282

Merged
merged 2 commits into from
Nov 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ addr2line = { version = "0.15", default-features = false, features = [
anyhow = "1"
colored = "2"
defmt-decoder = { version = "=0.3.0", features = ["unstable"] }
either = "1.6"
gimli = { version = "0.24", default-features = false }
git-version = "0.3"
log = "0.4"
Expand Down
1 change: 1 addition & 0 deletions src/backtrace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub(crate) struct Settings<'p> {
pub(crate) panic_present: bool,
pub(crate) backtrace_limit: u32,
pub(crate) shorten_paths: bool,
pub(crate) include_addresses: bool,
}

/// (virtually) unwinds the target's program and prints its backtrace
Expand Down
19 changes: 12 additions & 7 deletions src/backtrace/pp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Pretty printing the backtrace

use std::borrow::Cow;
use std::{borrow::Cow, fmt::Write};

use colored::Colorize as _;

Expand All @@ -20,18 +20,23 @@ pub(crate) fn backtrace(frames: &[Frame], settings: &Settings) {
}

Frame::Subroutine(subroutine) => {
let name = match &subroutine.name_or_pc {
either::Either::Left(name) => Cow::Borrowed(name),
either::Either::Right(pc) => Cow::Owned(format!("??? (PC={:#010x})", pc)),
};

let is_local_function = subroutine
.location
.as_ref()
.map(|location| location.path_is_relative)
.unwrap_or(false);

let line = format!("{:>4}: {}", frame_index, name);
let mut line = format!("{:>4}:", frame_index);
if settings.include_addresses || subroutine.name.is_none() {
write!(line, " {:#010x} @", subroutine.pc).unwrap();
}
write!(
line,
" {}",
subroutine.name.as_deref().unwrap_or("<unknown>")
)
.unwrap();

let colorized_line = if is_local_function {
line.bold()
} else {
Expand Down
20 changes: 7 additions & 13 deletions src/backtrace/symbolicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use std::{
};

use addr2line::fallible_iterator::FallibleIterator as _;
use either::Either;
use gimli::{EndianReader, RunTimeEndian};
use object::{Object as _, SymbolMap, SymbolMapName};

Expand Down Expand Up @@ -52,7 +51,8 @@ pub(crate) enum Frame {
/// "Symbolicated" and de-inlined subroutine frame
#[derive(Debug)]
pub(crate) struct Subroutine {
pub(crate) name_or_pc: Either<String, u32>,
pub(crate) name: Option<String>,
pub(crate) pc: u32,
pub(crate) location: Option<Location>,
}

Expand Down Expand Up @@ -116,9 +116,7 @@ impl Subroutine {

// XXX if there was inlining AND there's no function name info we'll report several
// frames with the same PC
let name_or_pc = demangled_name
.map(Either::Left)
.unwrap_or_else(|| name_from_symtab(pc, symtab));
let name = demangled_name.or_else(|| name_from_symtab(pc, symtab));

let location = if let Some((file, line, column)) =
frame.location.as_ref().and_then(|loc| {
Expand All @@ -142,24 +140,22 @@ impl Subroutine {
None
};

subroutines.push(Subroutine {
name_or_pc,
location,
})
subroutines.push(Subroutine { name, pc, location })
}

Some(subroutines)
}

fn from_symtab(pc: u32, symtab: &SymbolMap<SymbolMapName>) -> Subroutine {
Subroutine {
name_or_pc: name_from_symtab(pc, symtab),
name: name_from_symtab(pc, symtab),
pc,
location: None,
}
}
}

fn name_from_symtab(pc: u32, symtab: &SymbolMap<SymbolMapName>) -> Either<String, u32> {
fn name_from_symtab(pc: u32, symtab: &SymbolMap<SymbolMapName>) -> Option<String> {
// the .symtab appears to use address ranges that have their thumb bits set (e.g.
// `0x101..0x200`). Passing the `pc` with the thumb bit cleared (e.g. `0x100`) to the
// lookup function sometimes returns the *previous* symbol. Work around the issue by
Expand All @@ -169,8 +165,6 @@ fn name_from_symtab(pc: u32, symtab: &SymbolMap<SymbolMapName>) -> Either<String
symtab
.get(address)
.map(|symbol| addr2line::demangle_auto(symbol.name().into(), None).into_owned())
.map(Either::Left)
.unwrap_or(Either::Right(pc))
}

#[derive(Debug)]
Expand Down
4 changes: 2 additions & 2 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ pub(crate) struct Opts {
#[structopt(long)]
pub(crate) connect_under_reset: bool,

/// Enable more verbose logging.
/// Enable more verbose output.
#[structopt(short, long, parse(from_occurrences))]
verbose: u32,
pub(crate) verbose: u32,

/// Prints version information
#[structopt(short = "V", long)]
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ fn run_target_program(elf_path: &Path, chip_name: &str, opts: &cli::Opts) -> any
backtrace: (&opts.backtrace).into(),
panic_present,
shorten_paths: opts.shorten_paths,
include_addresses: opts.verbose > 0,
};

let mut outcome = backtrace::print(
Expand Down
33 changes: 21 additions & 12 deletions tests/snapshots/test__panic_verbose.snap
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ expression: run_result.output
(HOST) INFO flashing program (6.57 KiB)
(HOST) INFO success!
(HOST) DEBUG 261062 bytes of stack available (0x20000000 ..= 0x2003FBC7), using 1024 byte canary
(HOST) TRACE setting up canary took 0.012s (83.61 KiB/s)
(HOST) TRACE setting up canary took 0.014s (71.21 KiB/s)
(HOST) DEBUG starting device
(HOST) DEBUG Successfully attached RTT
────────────────────────────────────────────────────────────────────────────────
ERROR panicked at 'explicit panic'
────────────────────────────────────────────────────────────────────────────────
(HOST) TRACE reading canary took 0.011s (92.16 KiB/s)
(HOST) TRACE reading canary took 0.014s (72.39 KiB/s)
(HOST) DEBUG stack canary intact
(HOST) DEBUG LR=0xFFFFFFF9 PC=0x000015B0
(HOST) DEBUG LR=0x000001C9 PC=0x000008DE
Expand All @@ -37,26 +37,35 @@ ERROR panicked at 'explicit panic'
(HOST) DEBUG LR=0x0000018B PC=0x000001DC
(HOST) DEBUG update_cfa: CFA changed Some(2003fbc0) -> 2003fbc8
(HOST) DEBUG LR=0xFFFFFFFF PC=0x0000018A
(HOST) TRACE demangle Ok("_ZN3lib6inline5__udf17h4878bf20408765ceE") (language=Some(DwLang(1C))) -> Ok("lib::inline::__udf")
(HOST) TRACE demangle Ok("__udf") (language=Some(DwLang(1C))) -> Ok("__udf")
(HOST) TRACE demangle Ok("_ZN8cortex_m3asm3udf17h4c0f9f15c9bfd7bfE") (language=Some(DwLang(1C))) -> Ok("cortex_m::asm::udf")
(HOST) TRACE demangle Ok("_defmt_panic") (language=Some(DwLang(1C))) -> Ok("_defmt_panic")
(HOST) TRACE demangle Ok("_ZN5defmt6export5panic17h3fabd155b5d3f035E") (language=Some(DwLang(1C))) -> Ok("defmt::export::panic")
(HOST) TRACE demangle Ok("_ZN5panic18__cortex_m_rt_main17hdf4a9d08e66ae2a1E") (language=Some(DwLang(1C))) -> Ok("panic::__cortex_m_rt_main")
(HOST) TRACE demangle Ok("main") (language=Some(DwLang(1C))) -> Ok("main")
(HOST) TRACE demangle Ok("ResetTrampoline") (language=Some(DwLang(1C))) -> Ok("ResetTrampoline")
(HOST) TRACE demangle Ok("Reset") (language=Some(DwLang(1C))) -> Ok("Reset")
stack backtrace:
0: HardFaultTrampoline
0: 0x000015b0 @ HardFaultTrampoline
<exception entry>
1: lib::inline::__udf
1: 0x000008de @ lib::inline::__udf
at ./asm/inline.rs:172:5
2: __udf
2: 0x000008de @ __udf
at ./asm/lib.rs:49:17
3: cortex_m::asm::udf
3: 0x000001c8 @ cortex_m::asm::udf
at [cortex-m-0.7.3]/src/asm.rs:43:5
4: _defmt_panic
4: 0x000001d2 @ _defmt_panic
at /tmp/app/src/lib.rs:11:5
5: defmt::export::panic
5: 0x000001be @ defmt::export::panic
at /home/japaric/.cargo/git/checkouts/defmt-52fbd7917982cfac/e021e7d/src/export.rs:266:14
6: panic::__cortex_m_rt_main
6: 0x000001be @ panic::__cortex_m_rt_main
at /tmp/app/src/bin/panic.rs:8:5
7: main
7: 0x00000194 @ main
at /tmp/app/src/bin/panic.rs:6:1
8: ResetTrampoline
8: 0x000001dc @ ResetTrampoline
at [cortex-m-rt-0.6.14]/src/lib.rs:547:26
9: Reset
9: 0x0000018a @ Reset
at [cortex-m-rt-0.6.14]/src/lib.rs:550:13
(HOST) ERROR the program panicked