diag(kernel): log kdup attempts with handle kind and buf
Emits 'proc.kdup: id=N kind=K buf=B caller=C' on every kdup entry. This is the boot diagnostic used to determine that the relibc binary's spawn path uses the 'new-context' kdup (via ForkArgs::Init) rather than the 'fork' kdup (ForkArgs::Managed) that the relibc source code currently calls. The diagnostic itself stays in place for future debugging but the kernel proc handle ownership check from the earlier kernel work is not included here.
This commit is contained in:
+48
-3
@@ -1144,6 +1144,45 @@ impl KernelScheme for ProcScheme {
|
||||
_: CallerCtx,
|
||||
token: &mut CleanLockToken,
|
||||
) -> Result<OpenResult> {
|
||||
// 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("<binary>"),
|
||||
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 => {
|
||||
|
||||
Reference in New Issue
Block a user