diff options
| author | bors <bors@rust-lang.org> | 2017-07-06 17:15:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-07-06 17:15:14 +0000 |
| commit | cd72f2e269357ea4da4d0cf5502af35f4f9dab9e (patch) | |
| tree | e424f055b4be5c8e67a0358ebdebfabd546b4ffa /src/test | |
| parent | 54fc9e4ea587ad3ebb3ccb5c409ccfa9e4b09b3d (diff) | |
| parent | 5dbd97de3d825c6898df62baca33ff1f57cb77eb (diff) | |
| download | rust-cd72f2e269357ea4da4d0cf5502af35f4f9dab9e.tar.gz rust-cd72f2e269357ea4da4d0cf5502af35f4f9dab9e.zip | |
Auto merge of #42816 - alexcrichton:probestack, r=nikomatsakis
rustc: Implement stack probes for x86 This commit implements stack probes on x86/x86_64 using the freshly landed support upstream in LLVM. The purpose of stack probes here are to guarantee a segfault on stack overflow rather than having a chance of running over the guard page already present on all threads by accident. At this time there's no support for any other architecture because LLVM itself does not have support for other architectures.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/codegen/stack-probes.rs | 24 | ||||
| -rw-r--r-- | src/test/run-pass/stack-probes-lto.rs | 20 | ||||
| -rw-r--r-- | src/test/run-pass/stack-probes.rs | 68 |
3 files changed, 112 insertions, 0 deletions
diff --git a/src/test/codegen/stack-probes.rs b/src/test/codegen/stack-probes.rs new file mode 100644 index 00000000000..b7c794f4475 --- /dev/null +++ b/src/test/codegen/stack-probes.rs @@ -0,0 +1,24 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-arm +// ignore-wasm +// ignore-emscripten +// ignore-windows +// no-system-llvm +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +#[no_mangle] +pub fn foo() { +// CHECK: @foo() unnamed_addr #0 +// CHECK: attributes #0 = { {{.*}}"probe-stack"="__rust_probestack"{{.*}} } +} diff --git a/src/test/run-pass/stack-probes-lto.rs b/src/test/run-pass/stack-probes-lto.rs new file mode 100644 index 00000000000..045ba408137 --- /dev/null +++ b/src/test/run-pass/stack-probes-lto.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-arm +// ignore-wasm +// ignore-emscripten +// ignore-musl FIXME #31506 +// ignore-pretty +// no-system-llvm +// compile-flags: -C lto +// no-prefer-dynamic + +include!("stack-probes.rs"); diff --git a/src/test/run-pass/stack-probes.rs b/src/test/run-pass/stack-probes.rs new file mode 100644 index 00000000000..36aacea937a --- /dev/null +++ b/src/test/run-pass/stack-probes.rs @@ -0,0 +1,68 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-arm +// ignore-wasm +// ignore-emscripten +// ignore-musl FIXME #31506 +// no-system-llvm + +use std::mem; +use std::process::Command; +use std::thread; +use std::env; + +#[link(name = "rust_test_helpers", kind = "static")] +extern { + #[link_name = "rust_dbg_extern_identity_u64"] + fn black_box(u: u64); +} + +fn main() { + let args = env::args().skip(1).collect::<Vec<_>>(); + if args.len() > 0 { + match &args[0][..] { + "main-thread" => recurse(&[]), + "child-thread" => thread::spawn(|| recurse(&[])).join().unwrap(), + _ => panic!(), + } + return + } + + let me = env::current_exe().unwrap(); + + // The linux kernel has some different behavior for the main thread because + // the main thread's stack can typically grow. We can't always guarantee + // that we report stack overflow on the main thread, see #43052 for some + // details + if cfg!(not(target_os = "linux")) { + assert_overflow(Command::new(&me).arg("main-thread")); + } + assert_overflow(Command::new(&me).arg("child-thread")); +} + +#[allow(unconditional_recursion)] +fn recurse(array: &[u64]) { + unsafe { black_box(array.as_ptr() as u64); } + let local: [_; 1024] = unsafe { mem::uninitialized() }; + recurse(&local); +} + +fn assert_overflow(cmd: &mut Command) { + let output = cmd.output().unwrap(); + assert!(!output.status.success()); + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + println!("status: {}", output.status); + println!("stdout: {}", stdout); + println!("stderr: {}", stderr); + assert!(stdout.is_empty()); + assert!(stderr.contains("has overflowed its stack\n")); +} |
