alloc_error_handler tests: directly call handle_alloc_error; test more codepaths
This commit is contained in:
parent
8ad72b24f3
commit
d10f61313f
9 changed files with 122 additions and 75 deletions
|
|
@ -4,22 +4,7 @@
|
|||
#![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);
|
||||
handle_alloc_error(Layout::for_value(&0));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,10 @@ LL | ABORT();
|
|||
= 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);
|
||||
LL | handle_alloc_error(Layout::for_value(&0));
|
||||
| ^
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
//@compile-flags: -Cpanic=abort
|
||||
#![feature(start, core_intrinsics)]
|
||||
#![feature(alloc_error_handler)]
|
||||
#![feature(allocator_api)]
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::alloc::*;
|
||||
|
||||
extern "Rust" {
|
||||
fn miri_write_to_stderr(bytes: &[u8]);
|
||||
}
|
||||
|
||||
#[alloc_error_handler]
|
||||
fn alloc_error_handler(_: Layout) -> ! {
|
||||
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) -> ! {
|
||||
let msg = "custom panic handler called!\n";
|
||||
unsafe { miri_write_to_stderr(msg.as_bytes()) };
|
||||
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 {
|
||||
handle_alloc_error(Layout::for_value(&0));
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
custom alloc error handler called!
|
||||
error: abnormal termination: the program aborted execution
|
||||
--> $DIR/alloc_error_handler_custom.rs:LL:CC
|
||||
|
|
||||
LL | core::intrinsics::abort();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the program aborted execution
|
||||
|
|
||||
= note: BACKTRACE:
|
||||
= note: inside `alloc_error_handler` at $DIR/alloc_error_handler_custom.rs:LL:CC
|
||||
note: inside `_::__rg_oom`
|
||||
--> $DIR/alloc_error_handler_custom.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 `start`
|
||||
--> $DIR/alloc_error_handler_custom.rs:LL:CC
|
||||
|
|
||||
LL | handle_alloc_error(Layout::for_value(&0));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= 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
|
||||
|
||||
|
|
@ -7,28 +7,16 @@
|
|||
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!();
|
||||
}
|
||||
extern "Rust" {
|
||||
fn miri_write_to_stderr(bytes: &[u8]);
|
||||
}
|
||||
|
||||
#[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";
|
||||
// The default no_std alloc_error_handler is a panic.
|
||||
|
||||
#[panic_handler]
|
||||
fn panic_handler(_panic_info: &core::panic::PanicInfo) -> ! {
|
||||
let msg = "custom panic handler called!\n";
|
||||
unsafe { miri_write_to_stderr(msg.as_bytes()) };
|
||||
core::intrinsics::abort(); //~ERROR: aborted
|
||||
}
|
||||
|
|
@ -37,11 +25,6 @@ fn alloc_error_handler(_: Layout) -> ! {
|
|||
mod plumbing {
|
||||
use super::*;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
|
||||
core::intrinsics::abort();
|
||||
}
|
||||
|
||||
struct NoAlloc;
|
||||
|
||||
unsafe impl GlobalAlloc for NoAlloc {
|
||||
|
|
@ -60,6 +43,5 @@ mod plumbing {
|
|||
|
||||
#[start]
|
||||
fn start(_: isize, _: *const *const u8) -> isize {
|
||||
let _b = Box::new_in(0, BadAlloc);
|
||||
0
|
||||
handle_alloc_error(Layout::for_value(&0));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
custom alloc error handler called!
|
||||
custom panic handler called!
|
||||
error: abnormal termination: the program aborted execution
|
||||
--> $DIR/alloc_error_handler_no_std.rs:LL:CC
|
||||
|
|
||||
|
|
@ -6,24 +6,17 @@ 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 `panic_handler` at $DIR/alloc_error_handler_no_std.rs:LL:CC
|
||||
= note: inside `alloc::alloc::__alloc_error_handler::__rdl_oom` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||
= 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)
|
||||
LL | handle_alloc_error(Layout::for_value(&0));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
20
src/tools/miri/tests/panic/alloc_error_handler_hook.rs
Normal file
20
src/tools/miri/tests/panic/alloc_error_handler_hook.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#![feature(allocator_api, alloc_error_hook)]
|
||||
|
||||
use std::alloc::*;
|
||||
|
||||
struct Bomb;
|
||||
impl Drop for Bomb {
|
||||
fn drop(&mut self) {
|
||||
eprintln!("yes we are unwinding!");
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unreachable_code, unused_variables)]
|
||||
fn main() {
|
||||
// This is a particularly tricky hook, since it unwinds, which the default one does not.
|
||||
set_alloc_error_hook(|_layout| panic!("alloc error hook called"));
|
||||
|
||||
let bomb = Bomb;
|
||||
handle_alloc_error(Layout::for_value(&0));
|
||||
std::mem::forget(bomb); // defuse unwinding bomb
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
thread 'main' panicked at $DIR/alloc_error_handler_hook.rs:LL:CC:
|
||||
alloc error hook called
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||
yes we are unwinding!
|
||||
|
|
@ -2,21 +2,6 @@
|
|||
#![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 {
|
||||
|
|
@ -25,8 +10,9 @@ impl Drop for Bomb {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unreachable_code, unused_variables)]
|
||||
fn main() {
|
||||
let bomb = Bomb;
|
||||
let _b = Box::new_in(0, BadAlloc);
|
||||
handle_alloc_error(Layout::for_value(&0));
|
||||
std::mem::forget(bomb); // defuse unwinding bomb
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue