about summary refs log tree commit diff
path: root/src/test/ui/runtime
diff options
context:
space:
mode:
authorCaio <c410.f3r@gmail.com>2021-11-18 12:09:34 -0300
committerCaio <c410.f3r@gmail.com>2021-11-18 12:09:34 -0300
commit41d9abd76cd514aca23e3409fe6896a3a7d61d1a (patch)
treeaff7d6c42e88201c903006083095106fd082f16b /src/test/ui/runtime
parent6414e0b5b308d3ae27da83c6a25098cc8aadc1a9 (diff)
downloadrust-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.rs45
-rw-r--r--src/test/ui/runtime/backtrace-debuginfo-aux.rs14
-rw-r--r--src/test/ui/runtime/backtrace-debuginfo.rs188
-rw-r--r--src/test/ui/runtime/native-print-no-runtime.rs9
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
+}