about summary refs log tree commit diff
path: root/src/test/ui/allocator
diff options
context:
space:
mode:
authorHarald Hoyer <harald@redhat.com>2020-09-07 10:45:20 +0200
committerHarald Hoyer <harald@redhat.com>2020-10-02 09:00:29 +0200
commitcadd12b5f020b9b2c7bb0c5e7078b81fbdcfb6d8 (patch)
treef08cb851bfe4d02d97b2b20748a9f0d69d225ed0 /src/test/ui/allocator
parentf283d3f02cf3ed261a519afe05cde9e23d1d9278 (diff)
downloadrust-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.rs4
-rw-r--r--src/test/ui/allocator/no_std-alloc-error-handler-custom.rs97
-rw-r--r--src/test/ui/allocator/no_std-alloc-error-handler-default.rs84
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
+}