Skip to content

fix(libkernel): let pthread_kill with signal 0 report ESRCH for a thread that has ended - #8793

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
xXPBSXx:fix/pthread-kill-ended-thread-esrch
Oct 21, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
xXPBSXx:fix/pthread-kill-ended-thread-esrch

Conversation

@xXPBSXx

@xXPBSXx xXPBSXx commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

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 answers ESRCH (3). The calling thread still answers 0. GuestSignals gets the cases: a live thread -> 0; once it has returned -> ESRCH for signals 0 and 15; after scePthreadJoin -> 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) in thr_list.c, which returns ESRCH for 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. Family guest_signals, guest_sigtimedwait, guest_kill, guest_signal_sets, guest_sigaltstack: 5/5 pass. check_conventions --base upstream/main passes. 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) edits Signals.cpp and GuestSignals.cpp too and conflicts with this change; whichever lands second needs a small rebase.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes pthread_kill(thread, 0) answers 0 for a thread that has ended #8790
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

AI-assisted (Claude Code).

…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 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions github-actions Bot added the fix error Closes an issue (Fixes #N) label Oct 21, 2026

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@oneandonlydean
oneandonlydean merged commit cd700fe into boykopovar:main Oct 21, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs fix error Closes an issue (Fixes #N) libkernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pthread_kill(thread, 0) answers 0 for a thread that has ended

3 participants