]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
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 | ||
d9579d0f | 11 | // ignore-android FIXME #17520 |
2c00a5a8 | 12 | // ignore-cloudabi spawning processes is not supported |
5bcae85e | 13 | // ignore-emscripten spawning processes is not supported |
476ff2be | 14 | // ignore-openbsd no support for libbacktrace without filename |
7453a54e | 15 | // compile-flags:-g |
1a4d82fc | 16 | |
85aaf69f | 17 | use std::env; |
9346a6ac | 18 | use std::process::{Command, Stdio}; |
1a4d82fc JJ |
19 | use std::str; |
20 | ||
21 | #[inline(never)] | |
22 | fn foo() { | |
85aaf69f SL |
23 | let _v = vec![1, 2, 3]; |
24 | if env::var_os("IS_TEST").is_some() { | |
1a4d82fc JJ |
25 | panic!() |
26 | } | |
27 | } | |
28 | ||
29 | #[inline(never)] | |
30 | fn double() { | |
85aaf69f SL |
31 | struct Double; |
32 | ||
33 | impl Drop for Double { | |
34 | fn drop(&mut self) { panic!("twice") } | |
35 | } | |
36 | ||
37 | let _d = Double; | |
38 | ||
39 | panic!("once"); | |
1a4d82fc JJ |
40 | } |
41 | ||
9346a6ac AL |
42 | fn template(me: &str) -> Command { |
43 | let mut m = Command::new(me); | |
44 | m.env("IS_TEST", "1") | |
45 | .stdout(Stdio::piped()) | |
46 | .stderr(Stdio::piped()); | |
47 | return m; | |
48 | } | |
1a4d82fc | 49 | |
54a0048b | 50 | fn expected(fn_name: &str) -> String { |
8bb4bdeb | 51 | format!(" backtrace::{}", fn_name) |
54a0048b SL |
52 | } |
53 | ||
9346a6ac | 54 | fn runtest(me: &str) { |
1a4d82fc | 55 | // Make sure that the stack trace is printed |
9346a6ac | 56 | let p = template(me).arg("fail").env("RUST_BACKTRACE", "1").spawn().unwrap(); |
1a4d82fc JJ |
57 | let out = p.wait_with_output().unwrap(); |
58 | assert!(!out.status.success()); | |
9346a6ac | 59 | let s = str::from_utf8(&out.stderr).unwrap(); |
54a0048b | 60 | assert!(s.contains("stack backtrace") && s.contains(&expected("foo")), |
1a4d82fc | 61 | "bad output: {}", s); |
8bb4bdeb | 62 | assert!(s.contains(" 0:"), "the frame number should start at 0"); |
1a4d82fc JJ |
63 | |
64 | // Make sure the stack trace is *not* printed | |
c34b1796 AL |
65 | // (Remove RUST_BACKTRACE from our own environment, in case developer |
66 | // is running `make check` with it on.) | |
9346a6ac | 67 | let p = template(me).arg("fail").env_remove("RUST_BACKTRACE").spawn().unwrap(); |
1a4d82fc JJ |
68 | let out = p.wait_with_output().unwrap(); |
69 | assert!(!out.status.success()); | |
9346a6ac | 70 | let s = str::from_utf8(&out.stderr).unwrap(); |
54a0048b | 71 | assert!(!s.contains("stack backtrace") && !s.contains(&expected("foo")), |
1a4d82fc JJ |
72 | "bad output2: {}", s); |
73 | ||
54a0048b SL |
74 | // Make sure the stack trace is *not* printed |
75 | // (RUST_BACKTRACE=0 acts as if it were unset from our own environment, | |
76 | // in case developer is running `make check` with it set.) | |
77 | let p = template(me).arg("fail").env("RUST_BACKTRACE","0").spawn().unwrap(); | |
78 | let out = p.wait_with_output().unwrap(); | |
79 | assert!(!out.status.success()); | |
80 | let s = str::from_utf8(&out.stderr).unwrap(); | |
81 | assert!(!s.contains("stack backtrace") && !s.contains(" - foo"), | |
82 | "bad output3: {}", s); | |
83 | ||
1a4d82fc | 84 | // Make sure a stack trace is printed |
9346a6ac | 85 | let p = template(me).arg("double-fail").spawn().unwrap(); |
1a4d82fc JJ |
86 | let out = p.wait_with_output().unwrap(); |
87 | assert!(!out.status.success()); | |
9346a6ac | 88 | let s = str::from_utf8(&out.stderr).unwrap(); |
1a4d82fc JJ |
89 | // loosened the following from double::h to double:: due to |
90 | // spurious failures on mac, 32bit, optimized | |
54a0048b | 91 | assert!(s.contains("stack backtrace") && s.contains(&expected("double")), |
1a4d82fc JJ |
92 | "bad output3: {}", s); |
93 | ||
94 | // Make sure a stack trace isn't printed too many times | |
9346a6ac | 95 | let p = template(me).arg("double-fail") |
1a4d82fc JJ |
96 | .env("RUST_BACKTRACE", "1").spawn().unwrap(); |
97 | let out = p.wait_with_output().unwrap(); | |
98 | assert!(!out.status.success()); | |
9346a6ac | 99 | let s = str::from_utf8(&out.stderr).unwrap(); |
1a4d82fc | 100 | let mut i = 0; |
85aaf69f | 101 | for _ in 0..2 { |
c34b1796 | 102 | i += s[i + 10..].find("stack backtrace").unwrap() + 10; |
1a4d82fc | 103 | } |
c34b1796 | 104 | assert!(s[i + 10..].find("stack backtrace").is_none(), |
1a4d82fc JJ |
105 | "bad output4: {}", s); |
106 | } | |
107 | ||
108 | fn main() { | |
85aaf69f SL |
109 | let args: Vec<String> = env::args().collect(); |
110 | if args.len() >= 2 && args[1] == "fail" { | |
1a4d82fc | 111 | foo(); |
85aaf69f | 112 | } else if args.len() >= 2 && args[1] == "double-fail" { |
1a4d82fc JJ |
113 | double(); |
114 | } else { | |
85aaf69f | 115 | runtest(&args[0]); |
1a4d82fc JJ |
116 | } |
117 | } |