]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/backtrace.rs
5d65f9eb2be0fe3eb8b17738cdfdf248ebf0d288
[rust.git] / src / test / run-pass / backtrace.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // no-pretty-expanded FIXME #15189
12 // ignore-android FIXME #17520
13 // ignore-msvc FIXME #28133
14
15 use std::env;
16 use std::process::{Command, Stdio};
17 use std::str;
18 use std::ops::{Drop, FnMut, FnOnce};
19
20 #[inline(never)]
21 fn foo() {
22     let _v = vec![1, 2, 3];
23     if env::var_os("IS_TEST").is_some() {
24         panic!()
25     }
26 }
27
28 #[inline(never)]
29 fn double() {
30     struct Double;
31
32     impl Drop for Double {
33         fn drop(&mut self) { panic!("twice") }
34     }
35
36     let _d = Double;
37
38     panic!("once");
39 }
40
41 fn template(me: &str) -> Command {
42     let mut m = Command::new(me);
43     m.env("IS_TEST", "1")
44      .stdout(Stdio::piped())
45      .stderr(Stdio::piped());
46     return m;
47 }
48
49 fn runtest(me: &str) {
50     // Make sure that the stack trace is printed
51     let p = template(me).arg("fail").env("RUST_BACKTRACE", "1").spawn().unwrap();
52     let out = p.wait_with_output().unwrap();
53     assert!(!out.status.success());
54     let s = str::from_utf8(&out.stderr).unwrap();
55     assert!(s.contains("stack backtrace") && s.contains("foo::h"),
56             "bad output: {}", s);
57
58     // Make sure the stack trace is *not* printed
59     // (Remove RUST_BACKTRACE from our own environment, in case developer
60     // is running `make check` with it on.)
61     let p = template(me).arg("fail").env_remove("RUST_BACKTRACE").spawn().unwrap();
62     let out = p.wait_with_output().unwrap();
63     assert!(!out.status.success());
64     let s = str::from_utf8(&out.stderr).unwrap();
65     assert!(!s.contains("stack backtrace") && !s.contains("foo::h"),
66             "bad output2: {}", s);
67
68     // Make sure a stack trace is printed
69     let p = template(me).arg("double-fail").spawn().unwrap();
70     let out = p.wait_with_output().unwrap();
71     assert!(!out.status.success());
72     let s = str::from_utf8(&out.stderr).unwrap();
73     // loosened the following from double::h to double:: due to
74     // spurious failures on mac, 32bit, optimized
75     assert!(s.contains("stack backtrace") && s.contains("double::"),
76             "bad output3: {}", s);
77
78     // Make sure a stack trace isn't printed too many times
79     let p = template(me).arg("double-fail")
80                                 .env("RUST_BACKTRACE", "1").spawn().unwrap();
81     let out = p.wait_with_output().unwrap();
82     assert!(!out.status.success());
83     let s = str::from_utf8(&out.stderr).unwrap();
84     let mut i = 0;
85     for _ in 0..2 {
86         i += s[i + 10..].find("stack backtrace").unwrap() + 10;
87     }
88     assert!(s[i + 10..].find("stack backtrace").is_none(),
89             "bad output4: {}", s);
90 }
91
92 #[cfg(not(all(windows, target_arch = "x86")))]
93 fn main() {
94     let args: Vec<String> = env::args().collect();
95     if args.len() >= 2 && args[1] == "fail" {
96         foo();
97     } else if args.len() >= 2 && args[1] == "double-fail" {
98         double();
99     } else {
100         runtest(&args[0]);
101     }
102 }
103
104 // See issue 28218
105 #[cfg(all(windows, target_arch = "x86"))]
106 fn main() {}