Two fixes for the Pthread.robust_list_head field added in
P5-robust-mutexes:
1. create() at src/pthread/mod.rs:172 didn't initialize the
new_tcb.pthread.robust_list_head. The Tcb::new memory
happens to be zeroed, so the first non-main thread's first
pthread_mutex_lock of a ROBUST mutex would have
robust_list_head = 0 (null), which the original code at
src/sync/pthread_mutex.rs:301 dereferences with
'let mut node = unsafe { *head }' — that's a UB on null.
Add explicit init to null in create() so the invariant is
documented and future Tcb::new changes (e.g. switching to
MaybeUninit for performance) don't break the assumption.
2. mark_robust_mutexes_dead at src/sync/pthread_mutex.rs:299
dereferences *head without a null check. Even with the init
fix above, a thread may legitimately have an empty robust list
(never locked a robust mutex). Add the null guard so the
function is a no-op for empty lists.
Discovered by Oracle review of Phase 0c patches (Issue 4).
The init was missing because P5-robust-mutexes was applied as
an overlay patch that referenced the field but didn't include
the init line in the right scope.
Sys::open returns Result<i32, Errno> (not i32), and Sys::close
returns Result<i32, Errno> as well. The previous version of
mutex_owner_id_is_live used the cstr.as_ptr() pattern (which
the cross-compile correctly rejected because Sys::open expects
NulStr<'_, Thin> not *const c_char) and treated the Result as
a raw fd (which the type system rejected).
Fix: pass the CStr directly (it converts to NulStr via Deref)
and match on the Result<>'s Ok/Err variants instead of doing
fd >= 0 comparison on a non-i32 type.
P5-pthread-sigmask-race introduced PthreadFlags::FINISHED
handling in pthread_kill(). Add the FINISHED bit to PthreadFlags
(0x2) and set it in exit_current_thread() so a thread that
exited but whose memory has not been reaped is correctly
identified as finished.
P5-robust-mutexes references thread.robust_list_head and
crate::pthread::mutex_owner_id_is_live(). Add:
- Pthread.robust_list_head: UnsafeCell<*mut RobustMutexNode>
in src/pthread/mod.rs and src/ld_so/tcb.rs (both Pthread
construction sites)
- pub fn mutex_owner_id_is_live(owner: u32) -> bool in
src/pthread/mod.rs that probes the thread via the proc
scheme (Redox) or the OS_TID_TO_PTHREAD map (Linux)
P3-semaphore-comprehensive was un-applied at the merge state
because the next patch in the chain (P3-semaphore-varargs-header)
used the c_variadic unstable feature which is not enabled in
this toolchain. Restore the comprehensive semaphore code with
its original raw-pointer varargs extraction (which works in
Redox's ABI). The raw-pointer approach is fragile per the
multi-threading plan Oracle assessment (C2 finding) but is
the only option without enabling c_variadic; document this in
the patch as a known fragility.
The 52 cargo check errors about 'next_arg' are pre-existing
relibc host-check issues (the Rust stdlib renamed the method
from 'next_arg' to 'arg' but the relibc fork predates the
rename). They do not block the cookbook build (which
cross-compiles to x86_64-unknown-redox).