Skip to content

Commit

Permalink
Port backtrace's line-tables-only test over to rustc
Browse files Browse the repository at this point in the history
  • Loading branch information
jieyouxu committed Mar 22, 2024
1 parent b3df0d7 commit 4cc07d7
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3159,6 +3159,7 @@ impl Step for TestHelpers {
.opt_level(0)
.warnings(false)
.debug(false)
.flag("-g1")
.file(builder.src.join("tests/auxiliary/rust_test_helpers.c"))
.compile("rust_test_helpers");
}
Expand Down
15 changes: 15 additions & 0 deletions tests/auxiliary/rust_test_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,3 +427,18 @@ uint16_t issue_97463_leak_uninit_data(uint32_t a, uint32_t b, uint32_t c) {

return data->b; /* leak data */
}

// Used for testing backtrace inline_tables_only
typedef void (*inline_tables_only_callback) (void *data);

void inline_tables_only_baz(inline_tables_only_callback cb, void *data) {
cb(data);
}

void inline_tables_only_bar(inline_tables_only_callback cb, void *data) {
inline_tables_only_baz(cb, data);
}

void inline_tables_only_foo(inline_tables_only_callback cb, void *data) {
inline_tables_only_bar(cb, data);
}
56 changes: 56 additions & 0 deletions tests/ui/debuginfo/backtrace-inline-tables-only.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Test that when debug info only includes line tables that backtrace is still generated
// successfully. This previously failed when compiling with `clang -g1`.
// Part of <https://github.com/rust-lang/rust/issues/122899> porting some backtrace tests to rustc.
// ignore-tidy-linelength
//@ ignore-windows
//@ run-pass
//@ compile-flags: -Cdebuginfo=line-tables-only
#![feature(backtrace_frames)]

use std::backtrace::{self, Backtrace};
use std::ffi::c_void;
use std::ptr::addr_of_mut;

pub type Callback = extern "C" fn(data: *mut c_void);

#[link(name = "rust_test_helpers", kind = "static")]
extern "C" {
pub fn inline_tables_only_foo(cb: Callback, data: *mut c_void);
}

extern "C" fn store_backtrace(data: *mut c_void) {
let bt = backtrace::Backtrace::capture();
unsafe { *data.cast::<Option<Backtrace>>() = Some(bt) };
}

fn assert_contains(
backtrace: &Backtrace,
expected_name: &str,
expected_file: &str,
expected_line: u32,
) {
// FIXME(jieyouxu): fix this ugly fragile test when `BacktraceFrame` has accessors like...
// `symbols()`.
let backtrace = format!("{:#?}", backtrace);
eprintln!("{}", backtrace);
assert!(backtrace.contains(expected_name), "backtrace does not contain expected name {}", expected_name);
assert!(backtrace.contains(expected_file), "backtrace does not contain expected file {}", expected_file);
assert!(backtrace.contains(&expected_line.to_string()), "backtrace does not contain expected line {}", expected_line);
}

/// Verifies that when debug info includes only lines tables the generated
/// backtrace is still generated successfully. The test exercises behaviour
/// that failed previously when compiling with clang -g1.
///
/// The test case uses C rather than rust, since at that time when it was
/// written the debug info generated at level 1 in rustc was essentially
/// the same as at level 2.
fn main() {
std::env::set_var("RUST_BACKTRACE", "1");
let mut backtrace: Option<Backtrace> = None;
unsafe { inline_tables_only_foo(store_backtrace, addr_of_mut!(backtrace).cast::<c_void>()) };
let backtrace = backtrace.expect("backtrace");
assert_contains(&backtrace, "inline_tables_only_foo", "rust_test_helpers.c", 435);
assert_contains(&backtrace, "inline_tables_only_bar", "rust_test_helpers.c", 439);
assert_contains(&backtrace, "inline_tables_only_baz", "rust_test_helpers.c", 443);
}

0 comments on commit 4cc07d7

Please sign in to comment.