diff options
| author | Harald Hoyer <harald@redhat.com> | 2020-09-07 10:45:20 +0200 |
|---|---|---|
| committer | Harald Hoyer <harald@redhat.com> | 2020-10-02 09:00:29 +0200 |
| commit | cadd12b5f020b9b2c7bb0c5e7078b81fbdcfb6d8 (patch) | |
| tree | f08cb851bfe4d02d97b2b20748a9f0d69d225ed0 /src/test/ui/allocator | |
| parent | f283d3f02cf3ed261a519afe05cde9e23d1d9278 (diff) | |
| download | rust-cadd12b5f020b9b2c7bb0c5e7078b81fbdcfb6d8.tar.gz rust-cadd12b5f020b9b2c7bb0c5e7078b81fbdcfb6d8.zip | |
Implement Make `handle_alloc_error` default to panic (for no_std + liballoc)
Related: https://github.com/rust-lang/rust/issues/66741 Guarded with `#![feature(default_alloc_error_handler)]` a default `alloc_error_handler` is called, if a custom allocator is used and no other custom `#[alloc_error_handler]` is defined. The panic message does not contain the size anymore, because it would pull in the fmt machinery, which would blow up the code size significantly.
Diffstat (limited to 'src/test/ui/allocator')
| -rw-r--r-- | src/test/ui/allocator/auxiliary/helper.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/allocator/no_std-alloc-error-handler-custom.rs | 97 | ||||
| -rw-r--r-- | src/test/ui/allocator/no_std-alloc-error-handler-default.rs | 84 |
3 files changed, 184 insertions, 1 deletions
diff --git a/src/test/ui/allocator/auxiliary/helper.rs b/src/test/ui/allocator/auxiliary/helper.rs index 7f6770c226a..008fb3501d9 100644 --- a/src/test/ui/allocator/auxiliary/helper.rs +++ b/src/test/ui/allocator/auxiliary/helper.rs @@ -1,8 +1,10 @@ // no-prefer-dynamic #![crate_type = "rlib"] +#![no_std] -use std::fmt; +extern crate alloc; +use alloc::fmt; pub fn work_with(p: &fmt::Debug) { drop(p); diff --git a/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs b/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs new file mode 100644 index 00000000000..f09fafbc98a --- /dev/null +++ b/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs @@ -0,0 +1,97 @@ +// run-pass +// ignore-android no libc +// ignore-cloudabi no libc +// ignore-emscripten no libc +// ignore-sgx no libc +// ignore-wasm32 no libc +// only-linux +// compile-flags:-C panic=abort +// aux-build:helper.rs + +#![feature(start, rustc_private, new_uninit, panic_info_message)] +#![feature(alloc_error_handler)] +#![no_std] + +extern crate alloc; +extern crate libc; + +// ARM targets need these symbols +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr0() {} + +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr1() {} + +use core::ptr::null_mut; +use core::alloc::{GlobalAlloc, Layout}; +use alloc::boxed::Box; + +extern crate helper; + +struct MyAllocator; + +#[alloc_error_handler] +fn my_oom(layout: Layout) -> ! +{ + use alloc::fmt::write; + unsafe { + let size = layout.size(); + let mut s = alloc::string::String::new(); + write(&mut s, format_args!("My OOM: failed to allocate {} bytes!\n", size)).unwrap(); + let s = s.as_str(); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::exit(0) + } +} + +unsafe impl GlobalAlloc for MyAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if layout.size() < 4096 { + libc::malloc(layout.size()) as _ + } else { + null_mut() + } + } + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} +} + +#[global_allocator] +static A: MyAllocator = MyAllocator; + +#[panic_handler] +fn panic(panic_info: &core::panic::PanicInfo) -> ! { + unsafe { + if let Some(s) = panic_info.payload().downcast_ref::<&str>() { + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } + if let Some(args) = panic_info.message() { + let mut s = alloc::string::String::new(); + alloc::fmt::write(&mut s, *args).unwrap(); + let s = s.as_str(); + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } else { + const PSTR: &str = "panic occurred\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + } + libc::exit(1) + } +} + +#[derive(Debug)] +struct Page([[u64; 32]; 16]); + +#[start] +pub fn main(_argc: isize, _argv: *const *const u8) -> isize { + let zero = Box::<Page>::new_zeroed(); + let zero = unsafe { zero.assume_init() }; + helper::work_with(&zero); + 1 +} diff --git a/src/test/ui/allocator/no_std-alloc-error-handler-default.rs b/src/test/ui/allocator/no_std-alloc-error-handler-default.rs new file mode 100644 index 00000000000..4d68160379d --- /dev/null +++ b/src/test/ui/allocator/no_std-alloc-error-handler-default.rs @@ -0,0 +1,84 @@ +// run-pass +// ignore-android no libc +// ignore-cloudabi no libc +// ignore-emscripten no libc +// ignore-sgx no libc +// ignore-wasm32 no libc +// only-linux +// compile-flags:-C panic=abort +// aux-build:helper.rs +// gate-test-default_alloc_error_handler + +#![feature(start, rustc_private, new_uninit, panic_info_message)] +#![feature(default_alloc_error_handler)] +#![no_std] + +extern crate alloc; +extern crate libc; + +// ARM targets need these symbols +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr0() {} + +#[no_mangle] +pub fn __aeabi_unwind_cpp_pr1() {} + +use alloc::boxed::Box; +use core::alloc::{GlobalAlloc, Layout}; +use core::ptr::null_mut; + +extern crate helper; + +struct MyAllocator; + +unsafe impl GlobalAlloc for MyAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + if layout.size() < 4096 { + libc::malloc(layout.size()) as _ + } else { + null_mut() + } + } + unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} +} + +#[global_allocator] +static A: MyAllocator = MyAllocator; + +#[panic_handler] +fn panic(panic_info: &core::panic::PanicInfo) -> ! { + unsafe { + if let Some(s) = panic_info.payload().downcast_ref::<&str>() { + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } + if let Some(args) = panic_info.message() { + let mut s = alloc::string::String::new(); + alloc::fmt::write(&mut s, *args).unwrap(); + let s = s.as_str(); + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); + } else { + const PSTR: &str = "panic occurred\n"; + libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); + } + libc::exit(0) + } +} + +#[derive(Debug)] +struct Page([[u64; 32]; 16]); + +#[start] +pub fn main(_argc: isize, _argv: *const *const u8) -> isize { + let zero = Box::<Page>::new_zeroed(); + let zero = unsafe { zero.assume_init() }; + helper::work_with(&zero); + 1 +} |
