mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-04 03:07:25 +00:00
89 lines
2.2 KiB
Rust
89 lines
2.2 KiB
Rust
#![allow(unused_crate_dependencies)]
|
|
|
|
use std::env;
|
|
#[cfg(target_os = "linux")]
|
|
use std::os::unix::process::ExitStatusExt;
|
|
use std::process::{Command, ExitStatus, Stdio};
|
|
|
|
use rustc_thread_pool::ThreadPoolBuilder;
|
|
|
|
fn force_stack_overflow(depth: u32) {
|
|
let mut buffer = [0u8; 1024 * 1024];
|
|
#[allow(clippy::incompatible_msrv)]
|
|
std::hint::black_box(&mut buffer);
|
|
if depth > 0 {
|
|
force_stack_overflow(depth - 1);
|
|
}
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
fn disable_core() {
|
|
unsafe {
|
|
libc::setrlimit(libc::RLIMIT_CORE, &libc::rlimit { rlim_cur: 0, rlim_max: 0 });
|
|
}
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
fn overflow_code() -> Option<i32> {
|
|
None
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
fn overflow_code() -> Option<i32> {
|
|
use std::os::windows::process::ExitStatusExt;
|
|
|
|
ExitStatus::from_raw(0xc00000fd /*STATUS_STACK_OVERFLOW*/).code()
|
|
}
|
|
|
|
// FIXME: We should fix or remove this test on Windows.
|
|
#[test]
|
|
#[cfg_attr(not(any(unix)), ignore)]
|
|
fn stack_overflow_crash() {
|
|
// First check that the recursive call actually causes a stack overflow,
|
|
// and does not get optimized away.
|
|
let status = run_ignored("run_with_small_stack");
|
|
assert!(!status.success());
|
|
#[cfg(any(unix, windows))]
|
|
assert_eq!(status.code(), overflow_code());
|
|
#[cfg(target_os = "linux")]
|
|
assert!(matches!(status.signal(), Some(libc::SIGABRT | libc::SIGSEGV)));
|
|
|
|
// Now run with a larger stack and verify correct operation.
|
|
let status = run_ignored("run_with_large_stack");
|
|
assert_eq!(status.code(), Some(0));
|
|
#[cfg(target_os = "linux")]
|
|
assert_eq!(status.signal(), None);
|
|
}
|
|
|
|
fn run_ignored(test: &str) -> ExitStatus {
|
|
Command::new(env::current_exe().unwrap())
|
|
.arg("--ignored")
|
|
.arg("--exact")
|
|
.arg(test)
|
|
.stdout(Stdio::null())
|
|
.stderr(Stdio::null())
|
|
.status()
|
|
.unwrap()
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn run_with_small_stack() {
|
|
run_with_stack(8);
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn run_with_large_stack() {
|
|
run_with_stack(48);
|
|
}
|
|
|
|
fn run_with_stack(stack_size_in_mb: usize) {
|
|
let pool = ThreadPoolBuilder::new().stack_size(stack_size_in_mb * 1024 * 1024).build().unwrap();
|
|
pool.install(|| {
|
|
#[cfg(unix)]
|
|
disable_core();
|
|
force_stack_overflow(32);
|
|
});
|
|
}
|