logicaffeine_forge/
segv_trace.rs1#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
11pub fn install() {
12 use std::sync::Once;
13 static ONCE: Once = Once::new();
14 if std::env::var_os("LOGOS_SEGV_TRAP").is_none() {
15 return;
16 }
17 ONCE.call_once(|| unsafe {
18 let mut sa: libc::sigaction = std::mem::zeroed();
19 sa.sa_sigaction = handler as usize;
20 sa.sa_flags = libc::SA_SIGINFO;
21 libc::sigemptyset(&mut sa.sa_mask);
22 libc::sigaction(libc::SIGSEGV, &sa, std::ptr::null_mut());
23 libc::sigaction(libc::SIGBUS, &sa, std::ptr::null_mut());
24 });
25}
26
27#[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
28pub fn install() {}
29
30#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
31extern "C" fn handler(
32 sig: libc::c_int,
33 info: *mut libc::siginfo_t,
34 ucontext: *mut libc::c_void,
35) {
36 unsafe {
37 let addr_ptr = (info as *const u8).add(16) as *const usize;
40 let fault_addr = addr_ptr.read_unaligned();
41 let uc = ucontext as *const u8;
45 let greg = |i: usize| (uc.add(40 + i * 8) as *const i64).read_unaligned();
46 let (rdi, rsi, rdx, rax, rcx, rip) =
47 (greg(8), greg(9), greg(12), greg(13), greg(14), greg(16));
48 let r8 = greg(0);
49 let r9 = greg(1);
50 let rbx = greg(11);
51 let mut code = [0u8; 16];
53 for (k, b) in code.iter_mut().enumerate() {
54 *b = (rip as *const u8).add(k).read();
55 }
56 let msg = format!(
57 "\n*** LOGOS_SEGV_TRAP: sig {sig} fault=0x{fault_addr:016x} rip=0x{rip:016x}\n rdi(base)=0x{rdi:016x} rsi(sp)=0x{rsi:016x} rax=0x{rax:016x} rdx=0x{rdx:016x} rcx=0x{rcx:016x}\n r8=0x{r8:016x} r9=0x{r9:016x} rbx=0x{rbx:016x}\n code@rip={code:02x?} ***\n"
58 );
59 libc::write(2, msg.as_ptr() as *const libc::c_void, msg.len());
60 let mut sa: libc::sigaction = std::mem::zeroed();
62 sa.sa_sigaction = libc::SIG_DFL;
63 libc::sigemptyset(&mut sa.sa_mask);
64 libc::sigaction(sig, &sa, std::ptr::null_mut());
65 libc::raise(sig);
66 }
67}