Handle panic without TCB

This commit is contained in:
Wildan M
2026-07-06 16:08:59 +07:00
parent 77f87530c1
commit fbb56200ab
5 changed files with 48 additions and 38 deletions
+2 -9
View File
@@ -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"),
}
}
}
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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")
}
+37
View File
@@ -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)
}
}