diff --git a/bootstrap/src/procmgr.rs b/bootstrap/src/procmgr.rs index acff0940f0..a1cd24275c 100644 --- a/bootstrap/src/procmgr.rs +++ b/bootstrap/src/procmgr.rs @@ -542,6 +542,20 @@ enum Handle { SchemeRoot, } +// Red Bear diagnostic (2026-07-15): name a Handle variant for the boot-crash +// trace. randd's thr_fd resolves to procmgr (scheme 18) handle #8, which +// on_dup rejects with EBADF; this shows what kind #8 actually is. +fn handle_kind_str(h: &Handle) -> &'static str { + match h { + Handle::Init => "Init", + Handle::Proc(_) => "Proc", + Handle::Thread(_) => "Thread", + Handle::Ps(_) => "Ps", + Handle::ProcCredsCapability => "ProcCredsCapability", + Handle::SchemeRoot => "SchemeRoot", + } +} + #[derive(Clone, Copy, Debug)] enum WaitpidTarget { SingleProc(ProcessId), @@ -876,20 +890,45 @@ impl<'a> ProcScheme<'a> { } fn on_dup(&mut self, old_id: usize, buf: &[u8]) -> Result { log::trace!("Dup request"); + { + let kind = self.handles.get(old_id).map(handle_kind_str); + let _ = syscall::write( + 1, + alloc::format!( + "PROCMGR on_dup id={} kind={:?} buf={:?}\n", + old_id, + kind, + core::str::from_utf8(buf).unwrap_or("") + ) + .as_bytes(), + ); + } match self.handles[old_id] { Handle::Proc(pid) => match buf { b"fork" => { log::trace!("Forking {pid:?}"); let child_pid = self.fork(pid)?; + let number = self.handles.insert(Handle::Proc(child_pid)); + let _ = syscall::write( + 1, + alloc::format!("PROCMGR fork pid={:?} -> Proc handle={}\n", child_pid, number) + .as_bytes(), + ); Ok(OpenResult::ThisScheme { - number: self.handles.insert(Handle::Proc(child_pid)), + number, flags: NewFdFlags::empty(), }) } b"new-thread" => { let thread = self.new_thread(pid)?; + let number = self.handles.insert(Handle::Thread(Rc::downgrade(&thread))); + let _ = syscall::write( + 1, + alloc::format!("PROCMGR new-thread pid={:?} -> Thread handle={}\n", pid, number) + .as_bytes(), + ); Ok(OpenResult::ThisScheme { - number: self.handles.insert(Handle::Thread(Rc::downgrade(&thread))), + number, flags: NewFdFlags::empty(), }) } @@ -900,9 +939,18 @@ impl<'a> ProcScheme<'a> { .ok_or(Error::new(EINVAL))?; let process = self.processes.get(&pid).ok_or(Error::new(EBADFD))?.borrow(); let thread = Rc::downgrade(process.threads.get(idx).ok_or(Error::new(ENOENT))?); + let number = self.handles.insert(Handle::Thread(thread)); + let _ = syscall::write( + 1, + alloc::format!( + "PROCMGR thread-{} pid={:?} -> Thread handle={}\n", + idx, pid, number + ) + .as_bytes(), + ); return Ok(OpenResult::ThisScheme { - number: self.handles.insert(Handle::Thread(thread)), + number, flags: NewFdFlags::empty(), }); } @@ -2469,6 +2517,11 @@ impl<'a> ProcScheme<'a> { Ok(()) } fn on_close(&mut self, id: usize) { + let kind = self.handles.get(id).map(handle_kind_str); + let _ = syscall::write( + 1, + alloc::format!("PROCMGR on_close id={} kind={:?}\n", id, kind).as_bytes(), + ); if self.handles.try_remove(id).is_none() { log::error!("on_close for nonexistent handle, id={id}"); }