Skip to content

Commit 0cc5912

Browse files
bors[bot]cuviper
andauthored
Merge #1009
1009: Improve rayon-core/tests/stack_overflow_crash.rs r=cuviper a=cuviper - Rewrite it within the regular test harness, so it doesn't crash in arg-parsing on broad `cargo test -- filter` commands. - Use `std::hint::black_box` so the test even works in `--release`. Co-authored-by: Josh Stone <cuviper@gmail.com>
2 parents 1cacc82 + e4ba8d1 commit 0cc5912

File tree

2 files changed

+53
-41
lines changed

2 files changed

+53
-41
lines changed

rayon-core/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ libc = "0.2"
3333
[[test]]
3434
name = "stack_overflow_crash"
3535
path = "tests/stack_overflow_crash.rs"
36-
harness = false
3736

3837
# NB: having one [[test]] manually defined means we need to declare them all
3938

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use rayon_core::ThreadPoolBuilder;
22

33
use std::env;
4-
use std::process::Command;
4+
use std::process::{Command, ExitStatus, Stdio};
55

66
#[cfg(target_os = "linux")]
77
use std::os::unix::process::ExitStatusExt;
88

99
fn force_stack_overflow(depth: u32) {
10-
let _buffer = [0u8; 1024 * 1024];
10+
let mut buffer = [0u8; 1024 * 1024];
11+
std::hint::black_box(&mut buffer);
1112
if depth > 0 {
1213
force_stack_overflow(depth - 1);
1314
}
@@ -34,49 +35,61 @@ fn overflow_code() -> Option<i32> {
3435
#[cfg(windows)]
3536
fn overflow_code() -> Option<i32> {
3637
use std::os::windows::process::ExitStatusExt;
37-
use std::process::ExitStatus;
3838

3939
ExitStatus::from_raw(0xc00000fd /*STATUS_STACK_OVERFLOW*/).code()
4040
}
4141

42-
fn main() {
43-
if env::args().len() == 1 {
44-
// first check that the recursivecall actually causes a stack overflow, and does not get optimized away
45-
{
46-
let status = Command::new(env::current_exe().unwrap())
47-
.arg("8")
48-
.status()
49-
.unwrap();
42+
#[test]
43+
fn stack_overflow_crash() {
44+
// First check that the recursive call actually causes a stack overflow,
45+
// and does not get optimized away.
46+
let status = run_ignored("run_with_small_stack");
47+
#[cfg(any(unix, windows))]
48+
assert_eq!(status.code(), overflow_code());
49+
#[cfg(target_os = "linux")]
50+
assert!(matches!(
51+
status.signal(),
52+
Some(libc::SIGABRT | libc::SIGSEGV)
53+
));
5054

51-
#[cfg(any(unix, windows))]
52-
assert_eq!(status.code(), overflow_code());
55+
// Now run with a larger stack and verify correct operation.
56+
let status = run_ignored("run_with_large_stack");
57+
assert_eq!(status.code(), Some(0));
58+
#[cfg(target_os = "linux")]
59+
assert_eq!(status.signal(), None);
60+
}
5361

54-
#[cfg(target_os = "linux")]
55-
assert!(
56-
status.signal() == Some(11 /*SIGABRT*/) || status.signal() == Some(6 /*SIGSEGV*/)
57-
);
58-
}
62+
fn run_ignored(test: &str) -> ExitStatus {
63+
Command::new(env::current_exe().unwrap())
64+
.arg("--ignored")
65+
.arg("--exact")
66+
.arg(test)
67+
.stdout(Stdio::null())
68+
.stderr(Stdio::null())
69+
.status()
70+
.unwrap()
71+
}
5972

60-
// now run with a larger stack and verify correct operation
61-
{
62-
let status = Command::new(env::current_exe().unwrap())
63-
.arg("48")
64-
.status()
65-
.unwrap();
66-
assert_eq!(status.code(), Some(0));
67-
#[cfg(target_os = "linux")]
68-
assert_eq!(status.signal(), None);
69-
}
70-
} else {
71-
let stack_size_in_mb: usize = env::args().nth(1).unwrap().parse().unwrap();
72-
let pool = ThreadPoolBuilder::new()
73-
.stack_size(stack_size_in_mb * 1024 * 1024)
74-
.build()
75-
.unwrap();
76-
pool.install(|| {
77-
#[cfg(unix)]
78-
disable_core();
79-
force_stack_overflow(32);
80-
});
81-
}
73+
#[test]
74+
#[ignore]
75+
fn run_with_small_stack() {
76+
run_with_stack(8);
77+
}
78+
79+
#[test]
80+
#[ignore]
81+
fn run_with_large_stack() {
82+
run_with_stack(48);
83+
}
84+
85+
fn run_with_stack(stack_size_in_mb: usize) {
86+
let pool = ThreadPoolBuilder::new()
87+
.stack_size(stack_size_in_mb * 1024 * 1024)
88+
.build()
89+
.unwrap();
90+
pool.install(|| {
91+
#[cfg(unix)]
92+
disable_core();
93+
force_stack_overflow(32);
94+
});
8295
}

0 commit comments

Comments
 (0)