Files
RedBear-OS/local/patches/relibc/absorbed/P5-fatal-handler-diagnostics.patch
T
vasilito 5851974b20 feat: build system transition to release fork + archive hardening
Release fork infrastructure:
- REDBEAR_RELEASE=0.1.1 with offline enforcement (fetch/distclean/unfetch blocked)
- 195 BLAKE3-verified source archives in standard format
- Atomic provisioning via provision-release.sh (staging + .complete sentry)
- 5-phase improvement plan: restore format auto-detection, source tree
  validation (validate-source-trees.py), archive-map.json, REPO_BINARY fallback

Archive normalization:
- Removed 87 duplicate/unversioned archives from shared pool
- Regenerated all archives in consistent format with source/ + recipe.toml
- BLAKE3SUMS and manifest.json generated from stable tarball set

Patch management:
- verify-patches.sh: pre-sync dry-run report (OK/REVERSED/CONFLICT)
- 121 upstream-absorbed patches moved to absorbed/ directories
- 43 active patches verified clean against rebased sources
- Stress test: base updated to upstream HEAD, relibc reset and patched

Compilation fixes:
- relibc: Vec imports in redox-rt (proc.rs, lib.rs, sys.rs)
- relibc: unsafe from_raw_parts in mod.rs (2024 edition)
- fetch.rs: rev comparison handles short/full hash prefixes
- kibi recipe: corrected rev mismatch

New scripts: restore-sources.sh, provision-release.sh, verify-sources-archived.sh,
check-upstream-releases.sh, validate-source-trees.py, verify-patches.sh,
repair-archive-format.sh, generate-manifest.py

Documentation: AGENTS.md, README.md, local/AGENTS.md updated for release fork model
2026-05-02 01:41:17 +01:00

189 lines
5.5 KiB
Diff

diff --git a/src/lib.rs b/src/lib.rs
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -57,16 +57,151 @@ pub mod start;
pub mod sync;
-use crate::platform::{Allocator, NEWALLOCATOR};
+use crate::platform::{Allocator, NEWALLOCATOR, Pal, Sys};
#[global_allocator]
static ALLOCATOR: Allocator = NEWALLOCATOR;
+
+const MAX_FATAL_BACKTRACE_FRAMES: usize = 16;
+const MAX_FATAL_FRAME_STRIDE: usize = 1024 * 1024;
+
+#[inline(never)]
+fn write_process_thread_identity(w: &mut platform::FileWriter) {
+ use core::fmt::Write;
+
+ let pid = Sys::getpid();
+ let tid = Sys::gettid();
+
+ match crate::pthread::current_thread() {
+ Some(thread) => {
+ let _ = w.write_fmt(format_args!(
+ "RELIBC CONTEXT: pid={} tid={} pthread={:#x}\n",
+ pid,
+ tid,
+ thread as *const _ as usize,
+ ));
+ }
+ None => {
+ let _ = w.write_fmt(format_args!(
+ "RELIBC CONTEXT: pid={} tid={} pthread=<unavailable>\n",
+ pid, tid,
+ ));
+ }
+ }
+}
+
+#[cfg(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64"))]
+#[inline(never)]
+fn current_frame_pointer() -> *const usize {
+ let frame: *const usize;
+
+ #[cfg(target_arch = "x86_64")]
+ unsafe {
+ core::arch::asm!("mov {}, rbp", out(reg) frame, options(nomem, nostack, preserves_flags));
+ }
+
+ #[cfg(target_arch = "x86")]
+ unsafe {
+ core::arch::asm!("mov {}, ebp", out(reg) frame, options(nomem, nostack, preserves_flags));
+ }
+
+ #[cfg(target_arch = "aarch64")]
+ unsafe {
+ core::arch::asm!("mov {}, x29", out(reg) frame, options(nomem, nostack, preserves_flags));
+ }
+
+ frame
+}
+
+#[cfg(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64"))]
+fn read_backtrace_frame(frame: *const usize) -> Option<(*const usize, usize)> {
+ let align = core::mem::align_of::<usize>();
+ let frame_addr = frame as usize;
+
+ if frame.is_null() || frame_addr % align != 0 {
+ return None;
+ }
+
+ let next_frame = unsafe { frame.read() } as *const usize;
+ let return_address = unsafe { frame.add(1).read() };
+
+ if return_address == 0 {
+ return None;
+ }
+
+ Some((next_frame, return_address))
+}
+
+#[cfg(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64"))]
+fn is_sane_next_backtrace_frame(current: *const usize, next: *const usize) -> bool {
+ let align = core::mem::align_of::<usize>();
+ let current_addr = current as usize;
+ let next_addr = next as usize;
+
+ !next.is_null()
+ && next_addr % align == 0
+ && next_addr > current_addr
+ && next_addr - current_addr <= MAX_FATAL_FRAME_STRIDE
+}
+
+#[inline(never)]
+fn write_best_effort_backtrace(w: &mut platform::FileWriter) {
+ use core::fmt::Write;
+
+ let _ = w.write_str("RELIBC: attempting best-effort backtrace\n");
+
+ #[cfg(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64"))]
+ {
+ let mut frame = current_frame_pointer();
+ let mut wrote_frame = false;
+
+ for frame_index in 0..MAX_FATAL_BACKTRACE_FRAMES {
+ let Some((next_frame, return_address)) = read_backtrace_frame(frame) else {
+ break;
+ };
+
+ wrote_frame = true;
+ let _ = w.write_fmt(format_args!(
+ "RELIBC BACKTRACE[{frame_index:02}]: {:#x}\n",
+ return_address,
+ ));
+
+ if !is_sane_next_backtrace_frame(frame, next_frame) {
+ break;
+ }
+
+ frame = next_frame;
+ }
+
+ if !wrote_frame {
+ let _ = w.write_str("RELIBC: backtrace attempt produced no frames\n");
+ }
+ }
+
+ #[cfg(not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64")))]
+ {
+ let _ = w.write_str("RELIBC: backtrace unavailable on this architecture\n");
+ }
+}
#[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));
+
+ if let Some(location) = pi.location() {
+ let _ = w.write_fmt(format_args!(
+ "RELIBC PANIC LOCATION: {}:{}:{}\n",
+ location.file(),
+ location.line(),
+ location.column(),
+ ));
+ } else {
+ let _ = w.write_str("RELIBC PANIC LOCATION: <unavailable>\n");
+ }
+
+ write_process_thread_identity(&mut w);
+ let _ = w.write_fmt(format_args!("RELIBC PANIC: {}\n", pi));
core::intrinsics::abort();
}
@@ -95,23 +235,28 @@ pub extern "C" fn rust_oom(layout: ::core::alloc::Layout) -> ! {
let mut w = platform::FileWriter::new(2);
let _ = w.write_fmt(format_args!(
- "RELIBC OOM: {} bytes aligned to {} bytes\n",
+ "RELIBC OOM: {} bytes aligned to {} bytes - process will abort\n",
layout.size(),
layout.align()
));
+ write_process_thread_identity(&mut w);
+ write_best_effort_backtrace(&mut w);
core::intrinsics::abort();
}
#[cfg(not(test))]
#[allow(non_snake_case)]
#[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");
+ let _ = w.write_str(
+ "RELIBC: _Unwind_Resume called - exception propagation failed, aborting\n",
+ );
+ write_process_thread_identity(&mut w);
core::intrinsics::abort();
}