diff options
| author | Caio <c410.f3r@gmail.com> | 2021-11-18 12:09:34 -0300 |
|---|---|---|
| committer | Caio <c410.f3r@gmail.com> | 2021-11-18 12:09:34 -0300 |
| commit | 41d9abd76cd514aca23e3409fe6896a3a7d61d1a (patch) | |
| tree | aff7d6c42e88201c903006083095106fd082f16b /src/test/ui/runtime | |
| parent | 6414e0b5b308d3ae27da83c6a25098cc8aadc1a9 (diff) | |
| download | rust-41d9abd76cd514aca23e3409fe6896a3a7d61d1a.tar.gz rust-41d9abd76cd514aca23e3409fe6896a3a7d61d1a.zip | |
Move some tests to more reasonable directories
Diffstat (limited to 'src/test/ui/runtime')
| -rw-r--r-- | src/test/ui/runtime/atomic-print.rs | 45 | ||||
| -rw-r--r-- | src/test/ui/runtime/backtrace-debuginfo-aux.rs | 14 | ||||
| -rw-r--r-- | src/test/ui/runtime/backtrace-debuginfo.rs | 188 | ||||
| -rw-r--r-- | src/test/ui/runtime/native-print-no-runtime.rs | 9 |
4 files changed, 256 insertions, 0 deletions
diff --git a/src/test/ui/runtime/atomic-print.rs b/src/test/ui/runtime/atomic-print.rs new file mode 100644 index 00000000000..fe57910530f --- /dev/null +++ b/src/test/ui/runtime/atomic-print.rs @@ -0,0 +1,45 @@ +// run-pass + +#![allow(unused_must_use)] +#![allow(deprecated)] +// ignore-emscripten no threads support +// ignore-sgx no processes + +use std::{env, fmt, process, sync, thread}; + +struct SlowFmt(u32); +impl fmt::Debug for SlowFmt { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + thread::sleep_ms(3); + self.0.fmt(f) + } +} + +fn do_print(x: u32) { + let x = SlowFmt(x); + println!("{:?}{:?}{:?}{:?}{:?}", x, x, x, x, x); +} + +fn main(){ + if env::args().count() == 2 { + let barrier = sync::Arc::new(sync::Barrier::new(2)); + let tbarrier = barrier.clone(); + let t = thread::spawn(move || { + tbarrier.wait(); + do_print(1); + }); + barrier.wait(); + do_print(2); + t.join(); + } else { + let this = env::args().next().unwrap(); + let output = process::Command::new(this).arg("-").output().unwrap(); + for line in String::from_utf8(output.stdout).unwrap().lines() { + match line.chars().next().unwrap() { + '1' => assert_eq!(line, "11111"), + '2' => assert_eq!(line, "22222"), + chr => panic!("unexpected character {:?}", chr) + } + } + } +} diff --git a/src/test/ui/runtime/backtrace-debuginfo-aux.rs b/src/test/ui/runtime/backtrace-debuginfo-aux.rs new file mode 100644 index 00000000000..1411bcf89e8 --- /dev/null +++ b/src/test/ui/runtime/backtrace-debuginfo-aux.rs @@ -0,0 +1,14 @@ +// run-pass +// ignore-test: not a test, used by backtrace-debuginfo.rs to test file!() + +#[inline(never)] +pub fn callback<F>(f: F) where F: FnOnce((&'static str, u32)) { + f((file!(), line!())) +} + +// We emit the wrong location for the caller here when inlined on MSVC +#[cfg_attr(not(target_env = "msvc"), inline(always))] +#[cfg_attr(target_env = "msvc", inline(never))] +pub fn callback_inlined<F>(f: F) where F: FnOnce((&'static str, u32)) { + f((file!(), line!())) +} diff --git a/src/test/ui/runtime/backtrace-debuginfo.rs b/src/test/ui/runtime/backtrace-debuginfo.rs new file mode 100644 index 00000000000..b976c3a13bd --- /dev/null +++ b/src/test/ui/runtime/backtrace-debuginfo.rs @@ -0,0 +1,188 @@ +// run-pass +// We disable tail merging here because it can't preserve debuginfo and thus +// potentially breaks the backtraces. Also, subtle changes can decide whether +// tail merging succeeds, so the test might work today but fail tomorrow due to a +// seemingly completely unrelated change. +// Unfortunately, LLVM has no "disable" option for this, so we have to set +// "enable" to 0 instead. + +// compile-flags:-g -Copt-level=0 -Cllvm-args=-enable-tail-merge=0 +// compile-flags:-Cforce-frame-pointers=yes +// ignore-pretty issue #37195 +// ignore-emscripten spawning processes is not supported +// ignore-sgx no processes + +use std::env; + +#[path = "backtrace-debuginfo-aux.rs"] mod aux; + +macro_rules! pos { + () => ((file!(), line!())) +} + +macro_rules! dump_and_die { + ($($pos:expr),*) => ({ + // FIXME(#18285): we cannot include the current position because + // the macro span takes over the last frame's file/line. + // + // You might also be wondering why a major platform, + // i686-pc-windows-msvc, is located in here. Some of the saga can be + // found on #62897, but the tl;dr; is that it appears that if the + // standard library doesn't have debug information or frame pointers, + // which it doesn't by default on the test builders, then the stack + // walking routines in dbghelp will randomly terminate the stack trace + // in libstd without going further. Presumably the addition of frame + // pointers and/or debuginfo fixes this since tests always work with + // nightly compilers (which have debuginfo). In general though this test + // is replicated in rust-lang/backtrace-rs and has extensive coverage + // there, even on i686-pc-windows-msvc. We do the best we can in + // rust-lang/rust to test it as well, but sometimes we just gotta keep + // landing PRs. + if cfg!(any(target_os = "android", + all(target_os = "linux", target_arch = "arm"), + all(target_env = "msvc", target_arch = "x86"), + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd")) { + // skip these platforms as this support isn't implemented yet. + } else { + dump_filelines(&[$($pos),*]); + panic!(); + } + }) +} + +// we can't use a function as it will alter the backtrace +macro_rules! check { + ($counter:expr; $($pos:expr),*) => ({ + if *$counter == 0 { + dump_and_die!($($pos),*) + } else { + *$counter -= 1; + } + }) +} + +type Pos = (&'static str, u32); + +// this goes to stdout and each line has to be occurred +// in the following backtrace to stderr with a correct order. +fn dump_filelines(filelines: &[Pos]) { + for &(file, line) in filelines.iter().rev() { + // extract a basename + let basename = file.split(&['/', '\\'][..]).last().unwrap(); + println!("{}:{}", basename, line); + } +} + +#[inline(never)] +fn inner(counter: &mut i32, main_pos: Pos, outer_pos: Pos) { + check!(counter; main_pos, outer_pos); + check!(counter; main_pos, outer_pos); + let inner_pos = pos!(); aux::callback(|aux_pos| { + check!(counter; main_pos, outer_pos, inner_pos, aux_pos); + }); + let inner_pos = pos!(); aux::callback_inlined(|aux_pos| { + check!(counter; main_pos, outer_pos, inner_pos, aux_pos); + }); +} + +// We emit the wrong location for the caller here when inlined on MSVC +#[cfg_attr(not(target_env = "msvc"), inline(always))] +#[cfg_attr(target_env = "msvc", inline(never))] +fn inner_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos) { + check!(counter; main_pos, outer_pos); + check!(counter; main_pos, outer_pos); + + // Again, disable inlining for MSVC. + #[cfg_attr(not(target_env = "msvc"), inline(always))] + #[cfg_attr(target_env = "msvc", inline(never))] + fn inner_further_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) { + check!(counter; main_pos, outer_pos, inner_pos); + } + inner_further_inlined(counter, main_pos, outer_pos, pos!()); + + let inner_pos = pos!(); aux::callback(|aux_pos| { + check!(counter; main_pos, outer_pos, inner_pos, aux_pos); + }); + let inner_pos = pos!(); aux::callback_inlined(|aux_pos| { + check!(counter; 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(counter, main_pos, outer_pos, pos!()); +} + +#[inline(never)] +fn outer(mut counter: i32, main_pos: Pos) { + inner(&mut counter, main_pos, pos!()); + inner_inlined(&mut counter, main_pos, pos!()); +} + +fn check_trace(output: &str, error: &str) -> Result<(), String> { + // reverse the position list so we can start with the last item (which was the first line) + let mut remaining: Vec<&str> = output.lines().map(|s| s.trim()).rev().collect(); + + if !error.contains("stack backtrace") { + return Err(format!("no backtrace found in stderr:\n{}", error)) + } + for line in error.lines() { + if !remaining.is_empty() && line.contains(remaining.last().unwrap()) { + remaining.pop(); + } + } + if !remaining.is_empty() { + return Err(format!("trace does not match position list\n\ + still need to find {:?}\n\n\ + --- stdout\n{}\n\ + --- stderr\n{}", + remaining, output, error)) + } + Ok(()) +} + +fn run_test(me: &str) { + use std::str; + use std::process::Command; + + let mut i = 0; + let mut errors = Vec::new(); + loop { + let out = Command::new(me) + .env("RUST_BACKTRACE", "full") + .arg(i.to_string()).output().unwrap(); + let output = str::from_utf8(&out.stdout).unwrap(); + let error = str::from_utf8(&out.stderr).unwrap(); + if out.status.success() { + assert!(output.contains("done."), "bad output for successful run: {}", output); + break; + } else { + if let Err(e) = check_trace(output, error) { + errors.push(e); + } + } + i += 1; + } + if errors.len() > 0 { + for error in errors { + println!("---------------------------------------"); + println!("{}", error); + } + + panic!("found some errors"); + } +} + +#[inline(never)] +fn main() { + let args: Vec<String> = env::args().collect(); + if args.len() >= 2 { + let case = args[1].parse().unwrap(); + eprintln!("test case {}", case); + outer(case, pos!()); + println!("done."); + } else { + run_test(&args[0]); + } +} diff --git a/src/test/ui/runtime/native-print-no-runtime.rs b/src/test/ui/runtime/native-print-no-runtime.rs new file mode 100644 index 00000000000..f17c9fa6ca9 --- /dev/null +++ b/src/test/ui/runtime/native-print-no-runtime.rs @@ -0,0 +1,9 @@ +// run-pass + +#![feature(start)] + +#[start] +pub fn main(_: isize, _: *const *const u8) -> isize { + println!("hello"); + 0 +} |
