|
| 1 | +// Test that when debug info only includes line tables that backtrace is still generated |
| 2 | +// successfully. This previously failed when compiling with `clang -g1`. |
| 3 | +// Part of <https://github.com/rust-lang/rust/issues/122899> porting some backtrace tests to rustc. |
| 4 | +// ignore-tidy-linelength |
| 5 | +//@ ignore-windows |
| 6 | +//@ run-pass |
| 7 | +//@ compile-flags: -Cdebuginfo=line-tables-only |
| 8 | +#![feature(backtrace_frames)] |
| 9 | + |
| 10 | +use std::backtrace::{self, Backtrace}; |
| 11 | +use std::ffi::c_void; |
| 12 | +use std::ptr::addr_of_mut; |
| 13 | + |
| 14 | +pub type Callback = extern "C" fn(data: *mut c_void); |
| 15 | + |
| 16 | +#[link(name = "rust_test_helpers", kind = "static")] |
| 17 | +extern "C" { |
| 18 | + pub fn line_tables_only_foo(cb: Callback, data: *mut c_void); |
| 19 | +} |
| 20 | + |
| 21 | +extern "C" fn store_backtrace(data: *mut c_void) { |
| 22 | + let bt = backtrace::Backtrace::capture(); |
| 23 | + unsafe { *data.cast::<Option<Backtrace>>() = Some(bt) }; |
| 24 | +} |
| 25 | + |
| 26 | +fn assert_contains( |
| 27 | + backtrace: &Backtrace, |
| 28 | + expected_name: &str, |
| 29 | + expected_file: &str, |
| 30 | + expected_line: u32, |
| 31 | +) { |
| 32 | + // FIXME(jieyouxu): fix this ugly fragile test when `BacktraceFrame` has accessors like... |
| 33 | + // `symbols()`. |
| 34 | + let backtrace = format!("{:#?}", backtrace); |
| 35 | + eprintln!("{}", backtrace); |
| 36 | + assert!(backtrace.contains(expected_name), "backtrace does not contain expected name {}", expected_name); |
| 37 | + assert!(backtrace.contains(expected_file), "backtrace does not contain expected file {}", expected_file); |
| 38 | + assert!(backtrace.contains(&expected_line.to_string()), "backtrace does not contain expected line {}", expected_line); |
| 39 | +} |
| 40 | + |
| 41 | +/// Verifies that when debug info includes only lines tables the generated |
| 42 | +/// backtrace is still generated successfully. The test exercises behaviour |
| 43 | +/// that failed previously when compiling with clang -g1. |
| 44 | +/// |
| 45 | +/// The test case uses C rather than rust, since at that time when it was |
| 46 | +/// written the debug info generated at level 1 in rustc was essentially |
| 47 | +/// the same as at level 2. |
| 48 | +fn main() { |
| 49 | + std::env::set_var("RUST_BACKTRACE", "1"); |
| 50 | + let mut backtrace: Option<Backtrace> = None; |
| 51 | + unsafe { line_tables_only_foo(store_backtrace, addr_of_mut!(backtrace).cast::<c_void>()) }; |
| 52 | + let backtrace = backtrace.expect("backtrace"); |
| 53 | + assert_contains(&backtrace, "line_tables_only_foo", "rust_test_helpers.c", 435); |
| 54 | + assert_contains(&backtrace, "line_tables_only_bar", "rust_test_helpers.c", 439); |
| 55 | + assert_contains(&backtrace, "line_tables_only_baz", "rust_test_helpers.c", 443); |
| 56 | +} |
0 commit comments