diff options
| author | bors <bors@rust-lang.org> | 2024-04-16 20:20:34 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-04-16 20:20:34 +0000 |
| commit | 8ad72b24f3b7b09cd18ad21c8bf0876f23ec24fb (patch) | |
| tree | 6a0e2b7a60b08ba607765f7914d308140d0b9956 /src/tools/miri/tests | |
| parent | 719799028ad8c2dedccf3854db7d79fa5c852f84 (diff) | |
| parent | f325c8d4faca7e4885f7ce1d8ea92063eeecbd0c (diff) | |
| download | rust-8ad72b24f3b7b09cd18ad21c8bf0876f23ec24fb.tar.gz rust-8ad72b24f3b7b09cd18ad21c8bf0876f23ec24fb.zip | |
Auto merge of #3478 - RalfJung:alloc_error_handler, r=RalfJung
implement support for __rust_alloc_error_handler Fixes https://github.com/rust-lang/miri/issues/3439
Diffstat (limited to 'src/tools/miri/tests')
8 files changed, 186 insertions, 5 deletions
diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler.rs b/src/tools/miri/tests/fail/alloc/alloc_error_handler.rs new file mode 100644 index 00000000000..dc8e8c73800 --- /dev/null +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler.rs @@ -0,0 +1,25 @@ +//@error-in-other-file: aborted +//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();" +//@normalize-stderr-test: "\| +\^+" -> "| ^" +#![feature(allocator_api)] + +use std::alloc::*; +use std::ptr::NonNull; + +struct BadAlloc; + +// Create a failing allocator; Miri's native allocator never fails so this is the only way to +// actually call the alloc error handler. +unsafe impl Allocator for BadAlloc { + fn allocate(&self, _l: Layout) -> Result<NonNull<[u8]>, AllocError> { + Err(AllocError) + } + + unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) { + unreachable!(); + } +} + +fn main() { + let _b = Box::new_in(0, BadAlloc); +} diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr new file mode 100644 index 00000000000..f9d8e80c0fa --- /dev/null +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr @@ -0,0 +1,26 @@ +memory allocation of 4 bytes failed +error: abnormal termination: the program aborted execution + --> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC + | +LL | ABORT(); + | ^ the program aborted execution + | + = note: BACKTRACE: + = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC + = note: inside `std::process::abort` at RUSTLIB/std/src/process.rs:LL:CC + = note: inside `std::alloc::rust_oom` at RUSTLIB/std/src/alloc.rs:LL:CC + = note: inside `std::alloc::_::__rg_oom` at RUSTLIB/std/src/alloc.rs:LL:CC + = note: inside `std::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::boxed::Box::<i32, BadAlloc>::new_uninit_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC + = note: inside `std::boxed::Box::<i32, BadAlloc>::new_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC +note: inside `main` + --> $DIR/alloc_error_handler.rs:LL:CC + | +LL | let _b = Box::new_in(0, BadAlloc); + | ^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.rs b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.rs new file mode 100644 index 00000000000..8103296f47b --- /dev/null +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.rs @@ -0,0 +1,65 @@ +//@compile-flags: -Cpanic=abort +#![feature(start, core_intrinsics)] +#![feature(alloc_error_handler)] +#![feature(allocator_api)] +#![no_std] + +extern crate alloc; + +use alloc::alloc::*; +use alloc::boxed::Box; +use core::ptr::NonNull; + +struct BadAlloc; + +// Create a failing allocator; that is the only way to actually call the alloc error handler. +unsafe impl Allocator for BadAlloc { + fn allocate(&self, _l: Layout) -> Result<NonNull<[u8]>, AllocError> { + Err(AllocError) + } + + unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) { + unreachable!(); + } +} + +#[alloc_error_handler] +fn alloc_error_handler(_: Layout) -> ! { + extern "Rust" { + fn miri_write_to_stderr(bytes: &[u8]); + } + let msg = "custom alloc error handler called!\n"; + unsafe { miri_write_to_stderr(msg.as_bytes()) }; + core::intrinsics::abort(); //~ERROR: aborted +} + +// rustc requires us to provide some more things that aren't actually used by this test +mod plumbing { + use super::*; + + #[panic_handler] + fn panic_handler(_: &core::panic::PanicInfo) -> ! { + core::intrinsics::abort(); + } + + struct NoAlloc; + + unsafe impl GlobalAlloc for NoAlloc { + unsafe fn alloc(&self, _: Layout) -> *mut u8 { + unreachable!(); + } + + unsafe fn dealloc(&self, _: *mut u8, _: Layout) { + unreachable!(); + } + } + + #[global_allocator] + static GLOBAL: NoAlloc = NoAlloc; +} + +#[start] +fn start(_: isize, _: *const *const u8) -> isize { + let _b = Box::new_in(0, BadAlloc); + 0 +} diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr new file mode 100644 index 00000000000..b40ffb70121 --- /dev/null +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr @@ -0,0 +1,29 @@ +custom alloc error handler called! +error: abnormal termination: the program aborted execution + --> $DIR/alloc_error_handler_no_std.rs:LL:CC + | +LL | core::intrinsics::abort(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the program aborted execution + | + = note: BACKTRACE: + = note: inside `alloc_error_handler` at $DIR/alloc_error_handler_no_std.rs:LL:CC +note: inside `_::__rg_oom` + --> $DIR/alloc_error_handler_no_std.rs:LL:CC + | +LL | #[alloc_error_handler] + | ---------------------- in this procedural macro expansion +LL | fn alloc_error_handler(_: Layout) -> ! { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: inside `alloc::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `alloc::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `alloc::boxed::Box::<i32, BadAlloc>::new_uninit_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC + = note: inside `alloc::boxed::Box::<i32, BadAlloc>::new_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC +note: inside `start` + --> $DIR/alloc_error_handler_no_std.rs:LL:CC + | +LL | let _b = Box::new_in(0, BadAlloc); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/panic/alloc_error_handler_panic.rs b/src/tools/miri/tests/panic/alloc_error_handler_panic.rs new file mode 100644 index 00000000000..186c9667a97 --- /dev/null +++ b/src/tools/miri/tests/panic/alloc_error_handler_panic.rs @@ -0,0 +1,32 @@ +//@compile-flags: -Zoom=panic +#![feature(allocator_api)] + +use std::alloc::*; +use std::ptr::NonNull; + +struct BadAlloc; + +// Create a failing allocator; Miri's native allocator never fails so this is the only way to +// actually call the alloc error handler. +unsafe impl Allocator for BadAlloc { + fn allocate(&self, _l: Layout) -> Result<NonNull<[u8]>, AllocError> { + Err(AllocError) + } + + unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) { + unreachable!(); + } +} + +struct Bomb; +impl Drop for Bomb { + fn drop(&mut self) { + eprintln!("yes we are unwinding!"); + } +} + +fn main() { + let bomb = Bomb; + let _b = Box::new_in(0, BadAlloc); + std::mem::forget(bomb); // defuse unwinding bomb +} diff --git a/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr b/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr new file mode 100644 index 00000000000..202325468bf --- /dev/null +++ b/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr @@ -0,0 +1,4 @@ +thread 'main' panicked at RUSTLIB/std/src/alloc.rs:LL:CC: +memory allocation of 4 bytes failed +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +yes we are unwinding! diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.rs b/src/tools/miri/tests/pass/alloc-access-tracking.rs index 5c782fca2df..29c1ee2f7b7 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.rs +++ b/src/tools/miri/tests/pass/alloc-access-tracking.rs @@ -1,6 +1,6 @@ #![feature(start)] #![no_std] -//@compile-flags: -Zmiri-track-alloc-id=17 -Zmiri-track-alloc-accesses -Cpanic=abort +//@compile-flags: -Zmiri-track-alloc-id=18 -Zmiri-track-alloc-accesses -Cpanic=abort //@only-target-linux: alloc IDs differ between OSes for some reason extern "Rust" { diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.stderr b/src/tools/miri/tests/pass/alloc-access-tracking.stderr index 5e219fa1bed..bef13701ea2 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.stderr +++ b/src/tools/miri/tests/pass/alloc-access-tracking.stderr @@ -2,7 +2,7 @@ note: tracking was triggered --> $DIR/alloc-access-tracking.rs:LL:CC | LL | let ptr = miri_alloc(123, 1); - | ^^^^^^^^^^^^^^^^^^ created Miri bare-metal heap allocation of 123 bytes (alignment ALIGN bytes) with id 17 + | ^^^^^^^^^^^^^^^^^^ created Miri bare-metal heap allocation of 123 bytes (alignment ALIGN bytes) with id 18 | = note: BACKTRACE: = note: inside `start` at $DIR/alloc-access-tracking.rs:LL:CC @@ -11,7 +11,7 @@ note: tracking was triggered --> $DIR/alloc-access-tracking.rs:LL:CC | LL | *ptr = 42; // Crucially, only a write is printed here, no read! - | ^^^^^^^^^ write access to allocation with id 17 + | ^^^^^^^^^ write access to allocation with id 18 | = note: BACKTRACE: = note: inside `start` at $DIR/alloc-access-tracking.rs:LL:CC @@ -20,7 +20,7 @@ note: tracking was triggered --> $DIR/alloc-access-tracking.rs:LL:CC | LL | assert_eq!(*ptr, 42); - | ^^^^^^^^^^^^^^^^^^^^ read access to allocation with id 17 + | ^^^^^^^^^^^^^^^^^^^^ read access to allocation with id 18 | = note: BACKTRACE: = note: inside `start` at RUSTLIB/core/src/macros/mod.rs:LL:CC @@ -30,7 +30,7 @@ note: tracking was triggered --> $DIR/alloc-access-tracking.rs:LL:CC | LL | miri_dealloc(ptr, 123, 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ freed allocation with id 17 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ freed allocation with id 18 | = note: BACKTRACE: = note: inside `start` at $DIR/alloc-access-tracking.rs:LL:CC |
