Skip to content

Commit

Permalink
Auto merge of rust-lang#122958 - jieyouxu:port-backtrace-dylib-dep, r…
Browse files Browse the repository at this point in the history
…=workingjubilee

Port backtrace dylib-dep test to a ui test

Original test: [dylib-dep](https://github.com/rust-lang/backtrace-rs/tree/6fa4b85b9962c3e1be8c2e5cc605cd078134152b/crates/dylib-dep)
Part of rust-lang#122899.
  • Loading branch information
bors committed Mar 27, 2024
2 parents a1b4991 + 7764e8a commit 435b525
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 0 deletions.
17 changes: 17 additions & 0 deletions tests/ui/debuginfo/auxiliary/dylib-dep-helper-aux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//@ compile-flags: -g -Cstrip=none -Cforce-frame-pointers=yes

#[inline(never)]
pub fn callback<F>(f: F)
where
F: FnOnce((&'static str, u32)),
{
f((file!(), line!()))
}

#[inline(always)]
pub fn callback_inlined<F>(f: F)
where
F: FnOnce((&'static str, u32)),
{
f((file!(), line!()))
}
19 changes: 19 additions & 0 deletions tests/ui/debuginfo/auxiliary/dylib-dep-helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//@ compile-flags: -g -Cstrip=none -Cforce-frame-pointers=yes

#![crate_type = "cdylib"]
#![crate_type = "rlib"]

#![allow(improper_ctypes_definitions)]

type Pos = (&'static str, u32);

macro_rules! pos {
() => {
(file!(), line!())
};
}

#[no_mangle]
pub extern "C" fn foo(outer: Pos, inner: fn(Pos, Pos)) {
inner(outer, pos!());
}
114 changes: 114 additions & 0 deletions tests/ui/debuginfo/backtrace-dylib-dep.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// 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!())
};
}

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!());
}

0 comments on commit 435b525

Please sign in to comment.