]>
Commit | Line | Data |
---|---|---|
416331ca XL |
1 | // run-pass |
2 | ||
0bf4aa26 XL |
3 | #![allow(unused_must_use)] |
4 | #![allow(unconditional_recursion)] | |
94222f64 | 5 | #![allow(deprecated)] // llvm_asm! |
1a4d82fc | 6 | // ignore-android: FIXME (#20004) |
abe05a73 | 7 | // ignore-emscripten no processes |
48663c56 | 8 | // ignore-sgx no processes |
1a4d82fc | 9 | |
ba9703b0 | 10 | #![feature(llvm_asm)] |
0731742a | 11 | #![feature(rustc_private)] |
7453a54e SL |
12 | |
13 | #[cfg(unix)] | |
14 | extern crate libc; | |
1a4d82fc | 15 | |
85aaf69f | 16 | use std::env; |
e9174d1e SL |
17 | use std::process::Command; |
18 | use std::thread; | |
1a4d82fc JJ |
19 | |
20 | // lifted from the test module | |
21 | // Inlining to avoid llvm turning the recursive functions into tail calls, | |
22 | // which doesn't consume stack. | |
23 | #[inline(always)] | |
ba9703b0 | 24 | pub fn black_box<T>(dummy: T) { unsafe { llvm_asm!("" : : "r"(&dummy)) } } |
1a4d82fc JJ |
25 | |
26 | fn silent_recurse() { | |
e9174d1e | 27 | let buf = [0u8; 1000]; |
1a4d82fc JJ |
28 | black_box(buf); |
29 | silent_recurse(); | |
30 | } | |
31 | ||
32 | fn loud_recurse() { | |
33 | println!("hello!"); | |
34 | loud_recurse(); | |
35 | black_box(()); // don't optimize this into a tail call. please. | |
36 | } | |
37 | ||
7453a54e SL |
38 | #[cfg(unix)] |
39 | fn check_status(status: std::process::ExitStatus) | |
40 | { | |
7453a54e SL |
41 | use std::os::unix::process::ExitStatusExt; |
42 | ||
43 | assert!(!status.success()); | |
a7813a04 | 44 | assert_eq!(status.signal(), Some(libc::SIGABRT)); |
7453a54e SL |
45 | } |
46 | ||
47 | #[cfg(not(unix))] | |
48 | fn check_status(status: std::process::ExitStatus) | |
49 | { | |
50 | assert!(!status.success()); | |
51 | } | |
52 | ||
53 | ||
1a4d82fc | 54 | fn main() { |
85aaf69f SL |
55 | let args: Vec<String> = env::args().collect(); |
56 | if args.len() > 1 && args[1] == "silent" { | |
1a4d82fc | 57 | silent_recurse(); |
85aaf69f | 58 | } else if args.len() > 1 && args[1] == "loud" { |
1a4d82fc | 59 | loud_recurse(); |
e9174d1e SL |
60 | } else if args.len() > 1 && args[1] == "silent-thread" { |
61 | thread::spawn(silent_recurse).join(); | |
62 | } else if args.len() > 1 && args[1] == "loud-thread" { | |
63 | thread::spawn(loud_recurse).join(); | |
1a4d82fc | 64 | } else { |
e9174d1e SL |
65 | let mut modes = vec![ |
66 | "silent-thread", | |
67 | "loud-thread", | |
68 | ]; | |
69 | ||
70 | // On linux it looks like the main thread can sometimes grow its stack | |
71 | // basically without bounds, so we only test the child thread cases | |
72 | // there. | |
73 | if !cfg!(target_os = "linux") { | |
74 | modes.push("silent"); | |
75 | modes.push("loud"); | |
76 | } | |
77 | for mode in modes { | |
78 | println!("testing: {}", mode); | |
79 | ||
80 | let silent = Command::new(&args[0]).arg(mode).output().unwrap(); | |
7453a54e SL |
81 | |
82 | check_status(silent.status); | |
83 | ||
e9174d1e SL |
84 | let error = String::from_utf8_lossy(&silent.stderr); |
85 | assert!(error.contains("has overflowed its stack"), | |
86 | "missing overflow message: {}", error); | |
87 | } | |
1a4d82fc JJ |
88 | } |
89 | } |