Skip to content
Open
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
40 changes: 39 additions & 1 deletion library/std/src/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,10 @@ enum RawFrame {
Fake,
}

struct BacktraceSymbol {
/// A single symbol associated with a backtrace frame, which may include a
/// function name, filename, line number, and column number.
#[unstable(feature = "backtrace_internals_accessors", issue = "122899")]
pub struct BacktraceSymbol {
name: Option<Vec<u8>>,
filename: Option<BytesOrWide>,
lineno: Option<u32>,
Expand Down Expand Up @@ -207,6 +210,41 @@ impl fmt::Debug for BacktraceFrame {
}
}

///NOTE: This is never intended to become stable. It doesn't have an ACP
/// Its meant to help us port the tests mentioned in issue #122899
#[unstable(feature = "backtrace_internals_accessors", issue = "122899")]
impl BacktraceFrame {
/// Returns the instruction pointer associated with this frame.
pub fn ip(&self) -> *mut c_void {
self.frame.ip()
}

/// Returns the symbols associated with this frame, if any.
pub fn symbols(&self) -> &[BacktraceSymbol] {
&self.symbols
}

/// Returns the base address of the module this frame belongs to, if available.
pub fn module_base_address(&self) -> Option<*mut c_void> {
match &self.frame {
RawFrame::Actual(frame) => frame.module_base_address(),
#[cfg(test)]
RawFrame::Fake => None,
}
}
}

///NOTE: This is never intended to become stable. It doesn't have an ACP
/// Its meant to help us port the tests mentioned in issue #122899
impl BacktraceSymbol {
/// Returns the name of this symbol, if available.
#[unstable(feature = "backtrace_internals_accessors", issue = "122899")]
pub fn name(&self) -> Option<&[u8]> {
self.name.as_deref()
}
}

#[unstable(feature = "backtrace_internals_accessors", issue = "122899")]
impl fmt::Debug for BacktraceSymbol {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
// FIXME: improve formatting: https://github.com/rust-lang/rust/issues/65280
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,10 @@ See [RFC 3550 New Range](https://github.com/rust-lang/rfcs/blob/master/text/3550

Tests for Non-lexical lifetimes. See [RFC 2094 NLL](https://rust-lang.github.io/rfcs/2094-nll.html).

## `tests/ui/no_debuginfo`: without_debuginfo test ported from backtrace-rs

Tests for behavior when debug information is not available, ported from `backtrace-rs`'s `without_debuginfo` crate's test.

## `tests/ui/no_std/`

Tests for where the standard library is disabled through `#![no_std]`.
Expand Down
20 changes: 20 additions & 0 deletions tests/ui/no_debuginfo/all_frames_have_module_base_address.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ compile-flags: -Cstrip=none -Cdebuginfo=none
//@ run-pass
#![feature(backtrace_frames)]
#![feature(backtrace_internals_accessors)]
use std::backtrace;

fn main() {
let mut missing_base_addresses = 0;
let btrace = backtrace::Backtrace::force_capture();
let frames = btrace.frames();
for frame in frames {
if frame.module_base_address().is_none() {
missing_base_addresses += 1;
}
}

if cfg!(windows) {
assert_eq!(missing_base_addresses, 0);
}
}
44 changes: 44 additions & 0 deletions tests/ui/no_debuginfo/all_frames_have_symbols.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//@ compile-flags: -Cstrip=none -Cdebuginfo=none
//@ run-pass
#![feature(backtrace_frames)]
#![feature(backtrace_internals_accessors)]
use std::backtrace;
fn main() {
let mut missing_symbols = 0;
let mut has_symbols = 0;
let btrace = backtrace::Backtrace::force_capture();
let frames = btrace.frames();
let mut missing_symbol_indices = Vec::new();
for (i, frame) in frames.iter().enumerate() {
let mut any = false;
for sym in frame.symbols() {
if sym.name().is_some() {
any = true;
break;
}
}
if any {
has_symbols += 1;
} else if !frame.ip().is_null() {
missing_symbols += 1;
missing_symbol_indices.push(i);
}
}

// FIXME(#346) currently on MinGW we can't symbolize kernel32.dll and other
// system libraries, which means we miss the last few symbols.
if cfg!(windows) && cfg!(target_env = "gnu") {
assert!(missing_symbols < has_symbols && has_symbols > 4);
} else if cfg!(all(target_os = "linux", target_env = "gnu")) {
//NOTE: The reason we allow one missing symbol is because the frame for the
// `__libc_start_main` fn doesn't have a symbol. See the discussion in
// #152860 for more details.
assert!(missing_symbols < has_symbols && missing_symbols <= 1)
} else {
for i in missing_symbol_indices {
eprintln!("missing symbol for frame {i}: {:#?}", frames[i]);
}
eprintln!("Full erroneous backtrace: {:#?}", btrace);
assert_eq!(missing_symbols, 0);
}
Comment on lines +6 to +43
Copy link
Member

Choose a reason for hiding this comment

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

This isn't a known problem, so we may need to determine how many frames are missing symbols and it may be aarch64-unknown-linux-gnu specific.

Copy link
Member Author

Choose a reason for hiding this comment

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

Well it doesn't occur on my arm m2 mac so maybe it's specific? Might wanna check windows too to determine if it's x86

Copy link
Member

Choose a reason for hiding this comment

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

Huuuh.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops I misread the target. Do you mind if I rerun the CI for x86 Linux to try to repro the problem?

Copy link
Member Author

Choose a reason for hiding this comment

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

@workingjubilee I added some debug info to try to find the frame with the missing info. Also could #152870 be relevant to this?

}
Loading