Skip to content

Commit

Permalink
Merge pull request #158 from epage/backtrace
Browse files Browse the repository at this point in the history
fix: Clean up printing of backtraces
  • Loading branch information
epage authored Oct 10, 2024
2 parents 808aba7 + 8c6aa42 commit ba8a581
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 37 deletions.
66 changes: 32 additions & 34 deletions src/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,10 @@ impl Report {
}

fn render_backtrace() -> String {
//We skip 3 frames from backtrace library
//Then we skip 3 frames for our own library
//(including closure that we set as hook)
//Then we skip 2 functions from Rust's runtime
//that calls panic hook
const SKIP_FRAMES_NUM: usize = 8;
//We take padding for address and extra two letters
//to pad after index.
#[allow(unused_qualifications)] // needed for pre-1.80 MSRV
const HEX_WIDTH: usize = mem::size_of::<usize>() + 2;
const HEX_WIDTH: usize = mem::size_of::<usize>() * 2 + 2;
//Padding for next lines after frame's address
const NEXT_SYMBOL_PADDING: usize = HEX_WIDTH + 6;

Expand All @@ -95,40 +89,44 @@ fn render_backtrace() -> String {
//We need to print its address
//and symbol(e.g. function name),
//if it is available
for (idx, frame) in Backtrace::new()
let bt = Backtrace::new();
let symbols = bt
.frames()
.iter()
.skip(SKIP_FRAMES_NUM)
.enumerate()
{
let ip = frame.ip();
let _ = write!(backtrace, "\n{idx:4}: {ip:HEX_WIDTH$?}");

let symbols = frame.symbols();
if symbols.is_empty() {
let _ = write!(backtrace, " - <unresolved>");
continue;
}

for (idx, symbol) in symbols.iter().enumerate() {
//Print symbols from this address,
//if there are several addresses
//we need to put it on next line
if idx != 0 {
let _ = write!(backtrace, "\n{:1$}", "", NEXT_SYMBOL_PADDING);
}

if let Some(name) = symbol.name() {
let _ = write!(backtrace, " - {name}");
.flat_map(|frame| {
let symbols = frame.symbols();
if symbols.is_empty() {
vec![(frame, None, "<unresolved>".to_owned())]
} else {
let _ = write!(backtrace, " - <unknown>");
symbols
.iter()
.map(|s| {
(
frame,
Some(s),
s.name()
.map(|n| n.to_string())
.unwrap_or_else(|| "<unknown>".to_owned()),
)
})
.collect::<Vec<_>>()
}

})
.collect::<Vec<_>>();
let begin_unwind = "rust_begin_unwind";
let begin_unwind_start = symbols
.iter()
.position(|(_, _, n)| n == begin_unwind)
.unwrap_or(0);
for (entry_idx, (frame, symbol, name)) in symbols.iter().skip(begin_unwind_start).enumerate() {
let ip = frame.ip();
let _ = writeln!(backtrace, "{entry_idx:4}: {ip:HEX_WIDTH$?} - {name}");
if let Some(symbol) = symbol {
//See if there is debug information with file name and line
if let (Some(file), Some(line)) = (symbol.filename(), symbol.lineno()) {
let _ = write!(
let _ = writeln!(
backtrace,
"\n{:3$}at {}:{}",
"{:3$}at {}:{}",
"",
file.display(),
line,
Expand Down
20 changes: 20 additions & 0 deletions tests/single-panic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@ use human_panic::setup_panic;
fn main() {
setup_panic!();

call_inline_always()
}

fn call_inline_always() {
inline_always();
}

#[inline(always)]
fn inline_always() {
call_closure();
}

fn call_closure() {
let closure = || {
do_panic();
};
closure();
}

fn do_panic() {
println!("A normal log message");
panic!("OMG EVERYTHING IS ON FIRE!!!");
}
5 changes: 2 additions & 3 deletions tests/single-panic/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ Panic occurred in file 'tests/single-panic/src/main.rs' at line [..]
"cause" = "OMG EVERYTHING IS ON FIRE!!!"
"method" = "Panic"
"backtrace" = """
...
[..]"""
"""
"#]]
);
Expand All @@ -81,7 +80,7 @@ fn debug() {
.envs(envs)
.assert()
.stderr_eq(snapbox::str![[r#"
thread 'main' panicked at tests/single-panic/src/main.rs:7:5:
thread 'main' panicked at tests/single-panic/src/main.rs:[..]:
OMG EVERYTHING IS ON FIRE!!!
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Expand Down

0 comments on commit ba8a581

Please sign in to comment.