Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formatting of std::backtrace::Backtrace #284

Closed
wants to merge 13 commits into from
14 changes: 7 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
os: windows-latest
rust: nightly-i686-gnu
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@master
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come these revisions changed? (I don't think current syntax works unless it's v1)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was reading the existing PR on master and I swapped a few on accident, I'm planning on just force pushing to this branch with a new change from scratch so just ignore everything that's currently pushed

with:
submodules: true
- name: Install Rust (rustup)
Expand Down Expand Up @@ -86,7 +86,7 @@ jobs:
name: Windows AArch64
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@master
with:
submodules: true
- name: Install Rust
Expand Down Expand Up @@ -119,7 +119,7 @@ jobs:
- target: x86_64-apple-ios
sdk: iphonesimulator
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@master
with:
submodules: true
- name: Install Rust (
Expand Down Expand Up @@ -154,7 +154,7 @@ jobs:
- i686-linux-android
- x86_64-linux-android
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@master
with:
submodules: true
- name: Install Rust
Expand All @@ -167,7 +167,7 @@ jobs:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@master
with:
submodules: true
- name: Install Rust
Expand All @@ -181,7 +181,7 @@ jobs:
matrix:
target: [wasm32-unknown-unknown, wasm32-wasi, x86_64-fuchsia, x86_64-fortanix-unknown-sgx]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@master
with:
submodules: true
- name: Install Rust
Expand All @@ -193,7 +193,7 @@ jobs:
name: MSRV
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@master
with:
submodules: true
- name: Install Rust
Expand Down
6 changes: 5 additions & 1 deletion examples/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@ extern crate backtrace;
use backtrace::Backtrace;

fn main() {
println!("{:?}", Backtrace::new());
let backtrace = Backtrace::new();
println!("No Precision:\n{:?}\n", backtrace);
println!("No Precision Pretty:\n{:#?}\n", backtrace);
println!("Precision of 4:\n{:.4?}\n", backtrace);
println!("Precision of 4 Pretty:\n{:#.4?}", backtrace);
}
14 changes: 10 additions & 4 deletions src/capture.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::PrintFmt;
use crate::{resolve, resolve_frame, trace, BacktraceFmt, Symbol, SymbolName};
use crate::{resolve, resolve_frame, trace, BacktraceFmt, PrintFmt, Symbol, SymbolName};
use std::ffi::c_void;
use std::fmt;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -327,12 +326,19 @@ impl BacktraceSymbol {
impl fmt::Debug for Backtrace {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let full = fmt.alternate();
let precision = fmt.precision();

let (frames, style) = if full {
(&self.frames[..], PrintFmt::Full)
} else {
(&self.frames[self.actual_start_index..], PrintFmt::Short)
};

let frames = match precision {
Some(precision) => &frames[..precision],
None => frames,
};

// When printing paths we try to strip the cwd if it exists, otherwise
// we just print the path as-is. Note that we also only do this for the
// short format, because if it's full we presumably want to print
Expand All @@ -343,11 +349,11 @@ impl fmt::Debug for Backtrace {
if !full {
if let Ok(cwd) = &cwd {
if let Ok(suffix) = path.strip_prefix(cwd) {
return fmt::Display::fmt(&suffix.display(), fmt);
return write!(fmt, "{}", &suffix.display());
}
}
}
fmt::Display::fmt(&path.display(), fmt)
write!(fmt, "{}", &path.display())
};

let mut f = BacktraceFmt::new(fmt, style, &mut print_path);
Expand Down
61 changes: 28 additions & 33 deletions src/print.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::BytesOrWideString;
use cfg_if::cfg_if;
use core::ffi::c_void;
use core::fmt;

const HEX_WIDTH: usize = 2 + 2 * core::mem::size_of::<usize>();

#[cfg(target_os = "fuchsia")]
mod fuchsia;

Expand Down Expand Up @@ -57,9 +56,13 @@ impl<'a, 'b> BacktraceFmt<'a, 'b> {
/// sumbolicated later, and otherwise this should just be the first method
/// you call after creating a `BacktraceFmt`.
pub fn add_context(&mut self) -> fmt::Result {
self.fmt.write_str("stack backtrace:\n")?;
#[cfg(target_os = "fuchsia")]
fuchsia::print_dso_context(self.fmt)?;
cfg_if! {
if #[cfg(target_os = "fuchsia")] {
fuchsia::print_dso_context(self.fmt)?;
} else {
self.fmt.write_str("[")?;
}
}
Ok(())
}

Expand All @@ -69,18 +72,20 @@ impl<'a, 'b> BacktraceFmt<'a, 'b> {
/// to actually print a frame, and on destruction it will increment the
/// frame counter.
pub fn frame(&mut self) -> BacktraceFrameFmt<'_, 'a, 'b> {
let is_first_frame = self.frame_index == 0;
BacktraceFrameFmt {
fmt: self,
is_first_frame,
symbol_index: 0,
}
}

/// Completes the backtrace output.
///
/// This is currently a no-op but is added for future compatibility with
/// backtrace formats.
/// If not running on fuchsia, then close the list, otherwise this is a no-op.
pub fn finish(&mut self) -> fmt::Result {
// Currently a no-op-- including this hook to allow for future additions.
#[cfg(not(target_os = "fuchsia"))]
self.fmt.write_str("]")?;
Ok(())
}
}
Expand All @@ -90,6 +95,7 @@ impl<'a, 'b> BacktraceFmt<'a, 'b> {
/// This type is created by the `BacktraceFmt::frame` function.
pub struct BacktraceFrameFmt<'fmt, 'a, 'b> {
fmt: &'fmt mut BacktraceFmt<'a, 'b>,
is_first_frame: bool,
symbol_index: usize,
}

Expand Down Expand Up @@ -202,51 +208,40 @@ impl BacktraceFrameFmt<'_, '_, '_> {
frame_ip = usize::wrapping_sub(frame_ip as usize, image_base as _) as _;
}

// Print the index of the frame as well as the optional instruction
// pointer of the frame. If we're beyond the first symbol of this frame
// though we just print appropriate whitespace.
if self.symbol_index == 0 {
write!(self.fmt.fmt, "{:4}: ", self.fmt.frame_index)?;
if let PrintFmt::Full = self.fmt.format {
write!(self.fmt.fmt, "{:1$?} - ", frame_ip, HEX_WIDTH)?;
}
} else {
write!(self.fmt.fmt, " ")?;
if let PrintFmt::Full = self.fmt.format {
write!(self.fmt.fmt, "{:1$}", "", HEX_WIDTH + 3)?;
}
// If we are not printing the first frame, print a comma and space before opening the "map"
if !self.is_first_frame {
self.fmt.fmt.write_str(", ")?;
}
self.fmt.fmt.write_str("{ ")?;

// Next up write out the symbol name, using the alternate formatting for
// more information if we're a full backtrace. Here we also handle
// symbols which don't have a name,
match (symbol_name, &self.fmt.format) {
(Some(name), PrintFmt::Short) => write!(self.fmt.fmt, "{:#}", name)?,
(Some(name), PrintFmt::Full) => write!(self.fmt.fmt, "{}", name)?,
(None, _) | (_, PrintFmt::__Nonexhaustive) => write!(self.fmt.fmt, "<unknown>")?,
(Some(name), PrintFmt::Short) => write!(self.fmt.fmt, "function: \"{:#}\"", name)?,
(Some(name), PrintFmt::Full) => write!(self.fmt.fmt, "function: \"{}\"", name)?,
(None, _) | (_, PrintFmt::__Nonexhaustive) => {
write!(self.fmt.fmt, "function: \"<unknown>\"")?
}
}
self.fmt.fmt.write_str("\n")?;

// And last up, print out the filename/line number if they're available.
if let (Some(file), Some(line)) = (filename, lineno) {
self.print_fileline(file, line)?;
}

// Close the "map"
self.fmt.fmt.write_str(" }")?;

Ok(())
}

fn print_fileline(&mut self, file: BytesOrWideString, line: u32) -> fmt::Result {
// Filename/line are printed on lines under the symbol name, so print
// some appropriate whitespace to sort of right-align ourselves.
if let PrintFmt::Full = self.fmt.format {
write!(self.fmt.fmt, "{:1$}", "", HEX_WIDTH)?;
}
write!(self.fmt.fmt, " at ")?;

// Delegate to our internal callback to print the filename and then
// print out the line number.
self.fmt.fmt.write_str(", file: \"")?;
(self.fmt.print_path)(self.fmt.fmt, file)?;
write!(self.fmt.fmt, ":{}\n", line)?;
write!(self.fmt.fmt, "\", line: {}", line)?;
Ok(())
}

Expand Down