rust/tests/ui/backtrace/dylib-dep.rs
Jubilee Young d89500843c Move 100 entries from tests/ui into subdirs
- Move super-fast-paren-parsing test into ui/parser
- Move stmt_expr_attrs test into ui/feature-gates
- Move macro tests into ui/macros
- Move global_asm tests into ui/asm
- Move env tests into ui/process
- Move xcrate tests into ui/cross-crate
- Move unop tests into ui/unop
- Move backtrace tests into ui/backtrace
- Move check-static tests into ui/statics
- Move expr tests into ui/expr
- Move optimization fuel tests into ui/fuel
- Move ffi attribute tests into ui/ffi-attrs
- Move suggestion tests into ui/suggestions
- Move main tests into ui/fn-main
- Move lint tests into ui/lint
- Move repr tests into ui/repr
- Move intrinsics tests into ui/intrinsics
- Move tool lint tests into ui/tool-attributes
- Move return tests into ui/return
- Move pattern tests into ui/patttern
- Move range tests into ui/range
- Move foreign-fn tests into ui/foreign
- Move orphan-check tests into ui/coherence
- Move inference tests into ui/inference
- Reduce ROOT_ENTRY_LIMIT
2024-05-20 19:55:59 -07:00

116 lines
3.5 KiB
Rust

// Check that backtrace info is correctly generated for dynamic libraries and is usable by a
// rust binary.
// Part of porting some backtrace tests to rustc: <https://github.com/rust-lang/rust/issues/122899>.
// Original test:
// <https://github.com/rust-lang/backtrace-rs/tree/6fa4b85b9962c3e1be8c2e5cc605cd078134152b/crates/dylib-dep>
// ignore-tidy-linelength
//@ ignore-android FIXME #17520
//@ ignore-fuchsia Backtraces not symbolized
//@ ignore-musl musl doesn't support dynamic libraries (at least when the original test was written).
//@ needs-unwind
//@ compile-flags: -g -Copt-level=0 -Cstrip=none -Cforce-frame-pointers=yes
//@ aux-crate: dylib_dep_helper=dylib-dep-helper.rs
//@ aux-crate: auxiliary=dylib-dep-helper-aux.rs
//@ run-pass
#![allow(improper_ctypes)]
#![allow(improper_ctypes_definitions)]
extern crate dylib_dep_helper;
extern crate auxiliary;
use std::backtrace::Backtrace;
macro_rules! pos {
() => {
(file!(), line!())
};
}
#[collapse_debuginfo(yes)]
macro_rules! check {
($($pos:expr),*) => ({
verify(&[$($pos,)* pos!()]);
})
}
fn verify(filelines: &[Pos]) {
let trace = Backtrace::capture();
eprintln!("-----------------------------------");
eprintln!("looking for:");
for (file, line) in filelines.iter().rev() {
eprintln!("\t{file}:{line}");
}
eprintln!("found:\n{trace:#?}");
let mut iter = filelines.iter().rev();
// FIXME(jieyouxu): use proper `BacktraceFrame` accessors when it becomes available. Right now,
// this depends on the debug format of `Backtrace` which is of course fragile.
let backtrace = format!("{:#?}", trace);
while let Some((file, line)) = iter.next() {
// FIXME(jieyouxu): make this test use proper accessors on `BacktraceFrames` once it has
// them.
assert!(backtrace.contains(file), "expected backtrace to contain {}", file);
assert!(backtrace.contains(&line.to_string()), "expected backtrace to contain {}", line);
}
}
type Pos = (&'static str, u32);
extern "C" {
#[link_name = "foo"]
fn foo(p: Pos, cb: fn(Pos, Pos));
}
fn main() {
std::env::set_var("RUST_BACKTRACE", "1");
unsafe {
foo(pos!(), |a, b| {
check!(a, b)
})
}
outer(pos!());
}
#[inline(never)]
fn outer(main_pos: Pos) {
inner(main_pos, pos!());
inner_inlined(main_pos, pos!());
}
#[inline(never)]
fn inner(main_pos: Pos, outer_pos: Pos) {
check!(main_pos, outer_pos);
check!(main_pos, outer_pos);
let inner_pos = pos!(); auxiliary::callback(|aux_pos| {
check!(main_pos, outer_pos, inner_pos, aux_pos);
});
let inner_pos = pos!(); auxiliary::callback_inlined(|aux_pos| {
check!(main_pos, outer_pos, inner_pos, aux_pos);
});
}
#[inline(always)]
fn inner_inlined(main_pos: Pos, outer_pos: Pos) {
check!(main_pos, outer_pos);
check!(main_pos, outer_pos);
#[inline(always)]
fn inner_further_inlined(main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
check!(main_pos, outer_pos, inner_pos);
}
inner_further_inlined(main_pos, outer_pos, pos!());
let inner_pos = pos!(); auxiliary::callback(|aux_pos| {
check!(main_pos, outer_pos, inner_pos, aux_pos);
});
let inner_pos = pos!(); auxiliary::callback_inlined(|aux_pos| {
check!(main_pos, outer_pos, inner_pos, aux_pos);
});
// this tests a distinction between two independent calls to the inlined function.
// (un)fortunately, LLVM somehow merges two consecutive such calls into one node.
inner_further_inlined(main_pos, outer_pos, pos!());
}