cadd12b5f0
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.
98 lines
2.8 KiB
Rust
98 lines
2.8 KiB
Rust
// 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
|
|
}
|