Handle panic without TCB
This commit is contained in:
@@ -98,11 +98,6 @@ impl<Os> GenericTcb<Os> {
|
||||
unsafe { Some(&mut *Self::current_ptr()?) }
|
||||
}
|
||||
}
|
||||
pub fn panic_notls(_msg: impl core::fmt::Display) -> ! {
|
||||
// TODO: actually print _msg, perhaps by having panic_notls take a `T: DebugBackend` that can
|
||||
// propagate until called by e.g. relibc start
|
||||
core::intrinsics::abort();
|
||||
}
|
||||
|
||||
pub trait ExpectTlsFree {
|
||||
type Unwrapped;
|
||||
@@ -115,9 +110,7 @@ impl<T, E: core::fmt::Debug> ExpectTlsFree for Result<T, E> {
|
||||
fn expect_notls(self, msg: &str) -> T {
|
||||
match self {
|
||||
Ok(t) => t,
|
||||
Err(err) => panic_notls(format_args!(
|
||||
"{msg}: expect failed for Result with err: {err:?}",
|
||||
)),
|
||||
Err(err) => panic!("{msg}: expect failed for Result with err: {err:?}",),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,7 +120,7 @@ impl<T> ExpectTlsFree for Option<T> {
|
||||
fn expect_notls(self, msg: &str) -> T {
|
||||
match self {
|
||||
Some(t) => t,
|
||||
None => panic_notls(format_args!("{msg}: expect failed for Option")),
|
||||
None => panic!("{msg}: expect failed for Option"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,7 +541,7 @@ pub struct TmpDisableSignalsGuard {
|
||||
active: bool,
|
||||
}
|
||||
|
||||
/// Used to prevent EINTR from appearing across all syscall
|
||||
/// Used to disable jumping to signal handler while the guard active
|
||||
pub fn tmp_disable_signals() -> TmpDisableSignalsGuard {
|
||||
if !crate::TLS_ACTIVATED.load(Ordering::Relaxed) {
|
||||
return TmpDisableSignalsGuard { active: false };
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ pub mod linker;
|
||||
pub mod start;
|
||||
pub mod tcb;
|
||||
|
||||
pub use generic_rt::{ExpectTlsFree, panic_notls};
|
||||
pub use generic_rt::ExpectTlsFree;
|
||||
|
||||
static mut STATIC_TCB_MASTER: Master = Master {
|
||||
ptr: ptr::null_mut(),
|
||||
@@ -95,7 +95,7 @@ fn static_init(
|
||||
ph.p_vaddr(endian) as usize,
|
||||
)
|
||||
},
|
||||
_ => panic_notls(format_args!("unknown AT_PHENT size {}", phent)),
|
||||
_ => panic!("unknown AT_PHENT size {}", phent),
|
||||
};
|
||||
|
||||
let page_size = Sys::getpagesize();
|
||||
|
||||
+6
-26
@@ -48,6 +48,7 @@ pub mod io;
|
||||
pub mod iter;
|
||||
pub mod ld_so;
|
||||
pub mod out;
|
||||
pub mod panic;
|
||||
pub mod platform;
|
||||
pub mod pthread;
|
||||
pub mod raw_cell;
|
||||
@@ -59,21 +60,11 @@ use crate::platform::{Allocator, NEWALLOCATOR};
|
||||
#[global_allocator]
|
||||
static ALLOCATOR: Allocator = NEWALLOCATOR;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn relibc_panic(pi: &::core::panic::PanicInfo) -> ! {
|
||||
use core::fmt::Write;
|
||||
|
||||
let mut w = platform::FileWriter::new(2);
|
||||
let _ = w.write_fmt(format_args!("RELIBC PANIC: {}\n", pi));
|
||||
|
||||
core::intrinsics::abort();
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
#[linkage = "weak"]
|
||||
pub fn rust_begin_unwind(pi: &::core::panic::PanicInfo) -> ! {
|
||||
relibc_panic(pi)
|
||||
crate::panic::relibc_panic(pi)
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
@@ -87,17 +78,11 @@ pub extern "C" fn rust_eh_personality() {}
|
||||
#[allow(improper_ctypes_definitions)]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn rust_oom(layout: ::core::alloc::Layout) -> ! {
|
||||
// Layout not FFI-safe?
|
||||
use core::fmt::Write;
|
||||
|
||||
let mut w = platform::FileWriter::new(2);
|
||||
let _ = w.write_fmt(format_args!(
|
||||
"RELIBC OOM: {} bytes aligned to {} bytes\n",
|
||||
panic!(
|
||||
"RELIBC OOM: {} bytes aligned to {} bytes",
|
||||
layout.size(),
|
||||
layout.align()
|
||||
));
|
||||
|
||||
core::intrinsics::abort();
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
@@ -105,10 +90,5 @@ pub extern "C" fn rust_oom(layout: ::core::alloc::Layout) -> ! {
|
||||
#[linkage = "weak"]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn _Unwind_Resume() -> ! {
|
||||
use core::fmt::Write;
|
||||
|
||||
let mut w = platform::FileWriter::new(2);
|
||||
let _ = w.write_str("_Unwind_Resume\n");
|
||||
|
||||
core::intrinsics::abort();
|
||||
panic!("_Unwind_Resume")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
use core::fmt::Write;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn relibc_panic(pi: &::core::panic::PanicInfo) -> ! {
|
||||
use core::fmt::Write;
|
||||
|
||||
let mut w = PanicWriter::new();
|
||||
let _ = w.write_fmt(format_args!("RELIBC PANIC: {}\n", pi));
|
||||
|
||||
core::intrinsics::abort();
|
||||
}
|
||||
|
||||
struct PanicWriter;
|
||||
|
||||
impl PanicWriter {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for PanicWriter {
|
||||
fn write_str(&mut self, s: &str) -> core::fmt::Result {
|
||||
// Cannot use Sys::write, Tcb might not be available
|
||||
#[cfg(target_os = "redox")]
|
||||
{
|
||||
// TODO: init stderr ourself if it not ready.
|
||||
// Workaround: If stderr is not being prepared,
|
||||
// add debugging log at kernel write() syscall
|
||||
let _ = syscall::write(2, s.as_bytes());
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Non-redox platforms can directly write to stderr
|
||||
let mut w = crate::platform::FileWriter::new(2);
|
||||
w.write_str(s)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user