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 24, 2024
1 parent 6a92312 commit 698b9a3
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 4 deletions.
11 changes: 7 additions & 4 deletions src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1395,16 +1395,19 @@ impl Build {
// its caching system since we're executing quite a lot of tests and
// ideally shouldn't pollute the cache too much.
if let Some(path) = finder.maybe_have("wasmtime") {
if let Ok(mut path) = path.into_os_string().into_string() {
path.push_str(" run -C cache=n --dir .");
if let Ok(mut cmd) = path.into_os_string().into_string() {
cmd.push_str(" run -C cache=n --dir .");
// Make sure that tests have access to RUSTC_BOOTSTRAP. This (for example) is
// required for libtest to work on beta/stable channels.
//
// NB: with Wasmtime 20 this can change to `-S inherit-env` to
// inherit the entire environment rather than just this single
// environment variable.
path.push_str(" --env RUSTC_BOOTSTRAP");
return Some(path);
cmd.push_str(" --env RUSTC_BOOTSTRAP");
// Make sure debug-info is enabled so we can have backtraces with file names and
// line numbers.
cmd.push_str(" -D debug-info=y");
return Some(cmd);
}
}

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 line_tables_only
typedef void (*line_tables_only_callback) (void *data);

void line_tables_only_baz(line_tables_only_callback cb, void *data) {
cb(data);
}

void line_tables_only_bar(line_tables_only_callback cb, void *data) {
line_tables_only_baz(cb, data);
}

void line_tables_only_foo(line_tables_only_callback cb, void *data) {
line_tables_only_bar(cb, data);
}
61 changes: 61 additions & 0 deletions tests/ui/debuginfo/backtrace-line-tables-only.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// 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 original test is ignore-windows
//@ ignore-android FIXME #17520
//@ ignore-openbsd no support for libbacktrace without filename
//@ ignore-fuchsia Backtraces not symbolized
//@ needs-unwind
//@ run-pass
//@ compile-flags: -Cdebuginfo=line-tables-only -Cstrip=none
#![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 line_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");
std::env::set_var("WASMTIME_BACKTRACE_DETAILS", "1");
let mut backtrace: Option<Backtrace> = None;
unsafe { line_tables_only_foo(store_backtrace, addr_of_mut!(backtrace).cast::<c_void>()) };
let backtrace = backtrace.expect("backtrace");
assert_contains(&backtrace, "line_tables_only_foo", "rust_test_helpers.c", 435);
assert_contains(&backtrace, "line_tables_only_bar", "rust_test_helpers.c", 439);
assert_contains(&backtrace, "line_tables_only_baz", "rust_test_helpers.c", 443);
}

0 comments on commit 698b9a3

Please sign in to comment.