diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index 9ffd106b1d..f212f6ab41 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -1144,6 +1144,45 @@ impl KernelScheme for ProcScheme { _: CallerCtx, token: &mut CleanLockToken, ) -> Result { + // Red Bear diagnostic (2026-07-15): log the kdup attempt with + // the handle's current kind to help debug the relibc spawn + // race. This complements the duplicate_file diagnostic in + // syscall/fs.rs. + { + let handle_kind = { + let handles = HANDLES.read(token.token()); + handles.get(&old_id).map(|h| h.kind.clone()) + }; + match handle_kind { + Some(kind) => { + let kind_name = match &kind { + ContextHandle::Authority { .. } => "Authority", + ContextHandle::OpenViaDup { .. } => "OpenViaDup", + ContextHandle::Filetable { .. } => "Filetable", + ContextHandle::NewFiletable { .. } => "NewFiletable", + ContextHandle::Regs(_) => "Regs", + ContextHandle::AddrSpace { .. } => "AddrSpace", + ContextHandle::Sighandler { .. } => "Sighandler", + _ => "Other", + }; + let mut array = [0_u8; 64]; + let copy_len = raw_buf.len().min(array.len()); + let _ = raw_buf.copy_to_slice(&mut array[..copy_len]); + let caller_pid = context::current().read(token.token()).pid; + error!( + "proc.kdup: id={} kind={} buf={:?} caller={}", + old_id, + kind_name, + core::str::from_utf8(&array[..copy_len]).unwrap_or(""), + caller_pid + ); + } + None => { + error!("proc.kdup: id={} NOT_FOUND", old_id); + } + } + } + let info = { let handles = HANDLES.read(token.token()); let handle = handles.get(&old_id).ok_or(Error::new(EBADF))?; @@ -2002,9 +2041,15 @@ impl ContextHandle { read_from(buf, output.as_bytes(), offset) } ContextHandle::ProcUptime => { - let uptime_s = crate::time::monotonic(token) as f64 / crate::time::NANOS_PER_SEC as f64; - let idle_s = 0.0f64; - let output = format!("{:.2} {:.2}\n", uptime_s, idle_s); + // Red Bear fix (2026-07-15): kernel is built with + // `+soft-float` (no SSE), so f64 in format!() triggers + // "SSE register return with SSE disabled" build error. + // Use integer arithmetic and emit seconds.milliseconds + // without f64 division. uptime in seconds, idle always 0. + let nanos = crate::time::monotonic(token); + let uptime_s = nanos / crate::time::NANOS_PER_SEC; + let uptime_ms = (nanos % crate::time::NANOS_PER_SEC) / 1_000_000; + let output = format!("{}.{:02} 0.00\n", uptime_s, uptime_ms); read_from(buf, output.as_bytes(), offset) } ContextHandle::ProcLoadavg => {