Skip to content
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
16 changes: 9 additions & 7 deletions tests/ui/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# UI Test Suite Categories

This is a high-level summary of the organization of the UI test suite (`tests/ui/`). It is not intended to be *prescriptive*, but instead provide a quick survey of existing groupings.
This is a high-level summary of the organization of the UI test suite (`tests/ui/`). It is not intended to be _prescriptive_, but instead provide a quick survey of existing groupings.

For now, only immediate subdirectories under `tests/ui/` are described, but these subdirectories can themselves include a `SUMMARY.md` to further describe their own organization and intent, should that be helpful.

## `tests/ui/abi`

These tests deal with *Application Binary Interfaces* (ABI), mostly relating to function name mangling (and the `#[no_mangle]` attribute), calling conventions, or compiler flags which affect ABI.
These tests deal with _Application Binary Interfaces_ (ABI), mostly relating to function name mangling (and the `#[no_mangle]` attribute), calling conventions, or compiler flags which affect ABI.

Tests for unsupported ABIs can be made cross-platform by using the `extern "rust-invalid"` ABI, which is considered unsupported on every platform.

Expand Down Expand Up @@ -212,13 +212,13 @@ See [Conditional compilation | Reference](https://doc.rust-lang.org/reference/co

## `tests/ui/check-cfg/`: Configuration Checks

Tests for the `--check-cfg` compiler mechanism for checking cfg configurations, for `#[cfg(..)]` and `cfg!(..)`.
Tests for the `--check-cfg` compiler mechanism for checking cfg configurations, for `#[cfg(..)]` and `cfg!(..)`.

See [Checking conditional configurations | The rustc book](https://doc.rust-lang.org/rustc/check-cfg.html).

## `tests/ui/closure-expected-type/`: Closure type inference

Tests targeted at how we deduce the types of closure arguments. This process is a result of some heuristics which take into account the *expected type* we have alongside the *actual types* that we get from inputs.
Tests targeted at how we deduce the types of closure arguments. This process is a result of some heuristics which take into account the _expected type_ we have alongside the _actual types_ that we get from inputs.

**FIXME**: Appears to have significant overlap with `tests/ui/closure_context` and `tests/ui/functions-closures/closure-expected-type`. Needs further investigation.

Expand Down Expand Up @@ -286,7 +286,7 @@ This directory is actually for the standard library [`std::process::Command`](ht

Some traits' implementation must be compared with their definition, checking for problems such as the implementation having stricter requirements (such as needing to implement `Copy`).

This subdirectory is *not* intended for comparison traits (`PartialEq`, `Eq`, `PartialOrd`, `Ord`).
This subdirectory is _not_ intended comparison traits (`PartialEq`, `Eq`, `PartialOrd`, `Ord`).

## `tests/ui/compile-flags/`

Expand Down Expand Up @@ -700,6 +700,7 @@ This test category revolves around trait objects with `Sized` having illegal ope
Tests on lifetime elision in impl function signatures. See [Lifetime elision | Nomicon](https://doc.rust-lang.org/nomicon/lifetime-elision.html).

## `tests/ui/impl-restriction/`

Tests for `#![feature(impl_restriction)]`. See [Tracking issue for restrictions #105077](https://github.com/rust-lang/rust/issues/105077).

## `tests/ui/impl-trait/`
Expand Down Expand Up @@ -877,7 +878,7 @@ Tests on [AST lowering](https://rustc-dev-guide.rust-lang.org/ast-lowering.html)

## `tests/ui/lto/`

Exercise *Link-Time Optimization* (LTO), involving the flags `-C lto` or `-Z thinlto`.
Exercise _Link-Time Optimization_ (LTO), involving the flags `-C lto` or `-Z thinlto`.

## `tests/ui/lub-glb/`: LUB/GLB algorithm update

Expand Down Expand Up @@ -948,6 +949,7 @@ Tests on moves (destructive moves).
Broad category of tests on mutability, such as the `mut` keyword, borrowing a value as both immutable and mutable (and the associated error), or adding mutable references to `const` declarations.

## `tests/ui/mut-restriction/`

Tests for `#![feature(mut_restriction)]`. See [Tracking issue for restrictions #105077](https://github.com/rust-lang/rust/issues/105077).

## `tests/ui/namespace/`
Expand Down Expand Up @@ -1357,7 +1359,7 @@ Tests for supertrait item shadowing (RFC 3624).

## `tests/ui/svh/`: Strict Version Hash

Tests on the *Strict Version Hash* (SVH, also known as the "crate hash").
Tests on the _Strict Version Hash_ (SVH, also known as the "crate hash").

See [Strict Version Hash](https://rustc-dev-guide.rust-lang.org/backend/libs-and-metadata.html#strict-version-hash).

Expand Down
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);
}
}
45 changes: 45 additions & 0 deletions tests/ui/backtrace/no_debuginfo/all_frames_have_symbols.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//@ 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(rust-lang/backtrace-rs#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);
}
}
Loading