Repository navigation
fix(libkernel): let pthread_kill with signal 0 report ESRCH for a thread that has ended - #8793
Conversation
…ead that has ended pthread_kill(thread, 0) returned 0 for every handle other than the caller's before it asked whether the thread was still alive. FreeBSD's _pthread_kill looks the thread up with _thr_find_thread before it checks for signal 0, so the call answers ESRCH for a thread that has ended or was never a thread. The liveness check now runs before the signal 0 shortcut; the calling thread still answers 0. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
MarcZX10
left a comment
There was a problem hiding this comment.
Reviewed exact head 79569a7a3d78b654f443b4933305f8d9a1c84def. The order now checks non-self handles with GuestThreadIsLive before the signal-0 success path, while preserving signal 0 for self. The regression covers a live thread, an ended-but-not-yet-joined thread, the joined handle, and a fabricated pointer; GuestThreadIsLive checks registry identity under lock without dereferencing an unknown handle. Issue #8790 records the Windows behavior and compares it with FreeBSD 11.4. Conventions and diff checks pass. The author reports Windows focused tests passing; hosted Linux/Windows build and runtime jobs are skipped by path policy, so this review does not claim cross-platform execution. #3986 touches the same signal/test files but implements per-thread masks; its merge/rebase interaction is separate from this behavior.
MarcZX10
left a comment
There was a problem hiding this comment.
I reviewed the exact current head 79569a7a3d78b654f443b4933305f8d9a1c84def. The liveness-before-zero ordering, self-thread special case, fake handle coverage, and ended/joined thread cases all match the reported FreeBSD behavior. Windows focused tests are reported passing; platform build jobs are skipped by path policy, so I do not infer cross-platform runtime coverage. No additional code issue found.
What
Run the liveness check before the signal 0 shortcut in
pthread_kill, so signal 0 on a thread that has ended, been joined, or never existed answersESRCH(3). The calling thread still answers 0.GuestSignalsgets the cases: a live thread -> 0; once it has returned ->ESRCHfor signals 0 and 15; afterscePthreadJoin->ESRCH; a bogus handle with signal 0 ->ESRCH. The debt sentence about signal 0 is removed.Why
FreeBSD 11.4
_pthread_kill(thr_kill.c) with_thr_find_thread(..., include_dead = 0)inthr_list.c, which returnsESRCHfor a dead thread.Tested
Windows 10 Pro 19045, WinLibs GCC 15.2.0, Release.
guest_signals: without the change 3/3 fail (exit 0xc0000409), with it 3/3 pass. Familyguest_signals,guest_sigtimedwait,guest_kill,guest_signal_sets,guest_sigaltstack: 5/5 pass.check_conventions --base upstream/mainpasses. Not run: Linux, macOS, a title or console run. Console behaviour is not measured; the claim rests on FreeBSD's source only.Fixes #8790
Overlap
#8497 also edits
Signals.cpp(a different function); merge-tree against it is clean. #3986 (keep the signal mask per thread) editsSignals.cppandGuestSignals.cpptoo and conflicts with this change; whichever lands second needs a small rebase.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)AI-assisted (Claude Code).