Skip to content

fix(libkernel): reject ended threads in pthread_attr_get_np - #9482

Open
valenciana-nc wants to merge 1 commit into
boykopovar:mainfrom
valenciana-nc:fix/pthread-attr-ended-thread
Open

valenciana-nc wants to merge 1 commit into
boykopovar:mainfrom
valenciana-nc:fix/pthread-attr-ended-thread

Conversation

@valenciana-nc

@valenciana-nc valenciana-nc commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

What

Fix the documented ended-thread gap in pthread_attr_get_np: acquire the existing LockLiveGuestThread guard before reading the thread, and return guest ESRCH (3) when it is no longer live. Holding the registry lock through the attribute copy prevents detached-thread destruction from freeing the object during the read. The SCE sibling already uses this guard; validation order and live-thread attribute values are unchanged.

Extend GuestPthreadAttr.cpp to cover joined, finished-but-unjoined and detached threads, null arguments, unchanged stack-size attributes on failure, preserved guest errno, and successful self-queries during thread-specific-data destruction. Trim the resolved debt statement while retaining the unverified console behavior and Windows adopted-thread limitation.

The behavior follows the FreeBSD 11.4 implementation already cited by the debt entry: _pthread_attr_get_np calls _thr_find_thread with dead threads excluded. No new console measurement or title fix is claimed.

Refreshed head 271d428b2d1e55d9f38fdaa6af4b92876e83817c, based on audit-start main f57ceaad6bceeb00a7f4f09975f5932b2f20e28e. This supersedes the earlier rebase to b7d1d47a5f/head 6298429beb; git range-diff confirms the patch is unchanged. Unrelated upstream changes are preserved.

2026-10-24 status audit (no code update): head remains 271d428b2d; it still merges cleanly with fetched main 379b1dca32. No new implementation review request was posted. The earlier rebase/retest request was addressed in the comments below; re-review and maintainer-triggered runtime CI remain outstanding. No new execution result or unnecessary rebase is claimed.

The current overlap report still has debt-only hunks with #9684 and #9938. The #9684 author already agreed this PR first. The #9938 author documents either order as possible, specifically requiring its new joined-thread query case to expect ESRCH after this lifetime fix. Keeping #9482 first is consistent with its existing #9684 ordering; there is no new runtime dependency. Their supplied-stack implementation is not imported here, and no combined runtime test is claimed.

Previous audit's overlap review (historical integration observations):

Tested

Windows 11 x86-64 (build 26300.9711), WinLibs GCC 15.2.0 r7, Release, BUILD_TESTING=ON.

Last executed validation of 271d428b2d, base f57ceaad6b (not a new run against 2026-10-24 main):

  • Rebuilt all 26 guest_pthread*_tests executable targets, including current libkernel/libc. These register 27 pthread test cases.
  • ctest --test-dir build -R '^guest_pthread' --output-on-failure --parallel 4: 27/27 passed.
  • ctest --test-dir build -R '^guest_pthread_attr$' --repeat until-fail:25 --output-on-failure: 25 consecutive passes.
  • New-base negative control: temporarily removed only the two-line guard, kept the regression, confirmed git diff --exit-code main -- core/libs/prx, rebuilt, and reproduced pthread_attr_get_np returned 0, expected 3 (CTest exit 8). Restored the guard, rebuilt and reran the entire pthread group: 27/27 passed. Working tree clean afterward.
  • Conventions against synchronized origin/main, git diff --check main...HEAD, and overlap checker pass, with the limitations and manual review above.
  • Full suite and complete runnable-title runtime library set were not rebuilt/rerun after this rebase. No title run.

Historical full-suite validation, old head 892138ed5c, base a6dcea9279 (not results for this rebased head):

  • Regression failed first on unchanged main runtime-library sources; after the fix, 25 repeats and 27/27 pthread tests passed.
  • All buildable targets completed. At that base the full build was blocked by unchanged ImageArrayWindowPastLayerLimit.cpp:33: alignment 65536 exceeded the Windows object-file maximum 8192. That source has since changed upstream; this is not a claim about its current build status.
  • Full suite: 1,853 passed, 18 skipped, 3 failed, 1 not run, 288.22 seconds, exit 8. The unavailable test was agc_driver_image_array_window_past_layer_limit. Failures were agc_driver_sample_order, agc_driver_sample_order_grid_reference, and agc_driver_sample_order_recipe_depth_locations (depth/clear-value checks on the NVIDIA GeForce RTX 4060 Laptop GPU). All three reproduced with identical diagnostics after removing this fix and confirming runtime-library sources matched that main. No GPU code was changed.

No author-performed console, title, Linux or macOS testing for this PR. Independent Linux and WSL reviewers report red/green checks on old head 892138ed5c; they are not retests of the latest head. Hosted product builds require a maintainer-triggered run.

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: none
  • Unblocks: none
  • GPUs tested: n/a (libkernel-only change)
  • AI-assisted: yes

@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 the lifetime guard and failure-path tests. The function validates null arguments first, holds LockLiveGuestThread for the full attribute copy, and returns POSIX ESRCH when the registry no longer contains a live thread; this prevents detached-thread cleanup from racing the read. The test covers joined, finished-unjoined and detached threads, self-query from a thread-specific-data destructor, null inputs, unchanged destination attributes and unchanged guest errno. The author reports the focused pthread group passing 27/27 and 25 repeat runs, with full-suite failures reproduced on unchanged main and unrelated to this change. I compared the combined PR tree with #8041: the guard-size assignment and liveness check compose cleanly in the shared query, and both PRs’ separate focused tests remain present. Conventions, intake, eligibility, labels and report checks pass; hosted product jobs were skipped.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 9684 docs/dev/debt/libkernel.md L165-166
PR 9938 docs/dev/debt/libkernel.md L164-166

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 4630 docs/dev/debt/libkernel.md
PR 5021 docs/dev/debt/libkernel.md
PR 6044 core/libs/tests/GuestPthreadAttr.cpp
PR 6149 docs/dev/debt/libkernel.md
PR 6740 docs/dev/debt/libkernel.md
PR 6830 docs/dev/debt/libkernel.md
PR 6936 docs/dev/debt/libkernel.md
PR 7049 docs/dev/debt/libkernel.md
PR 7088 docs/dev/debt/libkernel.md
PR 7105 docs/dev/debt/libkernel.md
PR 7121 docs/dev/debt/libkernel.md
PR 7149 docs/dev/debt/libkernel.md
PR 7509 docs/dev/debt/libkernel.md
PR 7511 docs/dev/debt/libkernel.md
PR 7653 docs/dev/debt/libkernel.md
PR 8010 docs/dev/debt/libkernel.md
PR 8520 docs/dev/debt/libkernel.md
PR 8553 docs/dev/debt/libkernel.md
PR 9074 docs/dev/debt/libkernel.md
PR 9123 docs/dev/debt/libkernel.md
PR 9133 docs/dev/debt/libkernel.md
PR 9156 docs/dev/debt/libkernel.md
PR 9160 core/libs/prx/libkernel/Pthread/Posix/Attr.cpp
docs/dev/debt/libkernel.md
PR 9199 docs/dev/debt/libkernel.md
PR 9284 docs/dev/debt/libkernel.md
PR 9293 docs/dev/debt/libkernel.md
PR 9297 docs/dev/debt/libkernel.md
PR 9302 docs/dev/debt/libkernel.md
PR 9557 docs/dev/debt/libkernel.md
PR 9561 docs/dev/debt/libkernel.md
PR 9566 docs/dev/debt/libkernel.md
PR 9575 docs/dev/debt/libkernel.md
PR 9669 docs/dev/debt/libkernel.md
PR 9693 docs/dev/debt/libkernel.md
PR 10319 docs/dev/debt/libkernel.md

@jotitadev jotitadev 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.

Linux run of the current change, since the description lists only Windows ("No console, title, Linux or macOS testing").

Machine: Linux x86_64, i7-8700 (6 cores / 12 threads), Ubuntu 26.04, GCC 15.2, Release, BUILD_TESTING=ON. Head 892138ed5 merged onto main a6dcea927 (the merge touches only Attr.cpp, GuestPthreadAttr.cpp and the debt doc).

  • Build ok. guest_pthread_attr passes with the change (joined, finished-but-unjoined and detached threads, null arguments, preserved errno and the self-query cases).
  • Restoring libkernel/Pthread/Posix/Attr.cpp to main and keeping the test aborts guest_pthread_attr: on main pthread_attr_get_np returns 0 for an ended thread where the test expects guest ESRCH (3). So the regression reproduces on Linux as well and the test covers the change.

Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.

@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.

Rechecked the lifetime guard and latest follow-up test report. LockLiveGuestThread remains held for the full attribute copy, returns POSIX ESRCH for ended threads, and the new tests preserve validation order, guest errno and output attributes on failure. The author reports the Windows 27-test pthread group and 25 repeats; a later reviewer also reports a Linux build/test pass and a main-runtime negative control that reproduces the bug. Full-suite GPU failures are reported as reproducible on main and unrelated. Hosted policy checks pass; product jobs are skipped. I did not run local tests.

@xXPBSXx

xXPBSXx commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Linux data point for 892138ed5c: WSL2 Ubuntu 24.04 (virtualised kernel, not bare-metal), GCC 13.3.0, Release, BUILD_TESTING=ON, PR head alone (not merged onto main; its merge-base is a6dcea927).

  • With the PR: ctest -R '^guest_pthread_attr$' passes 3 of 3.
  • With libkernel/Pthread/Posix/Attr.cpp restored to the merge-base (the PR's tests kept): fails (Subprocess aborted).
    Not tested: macOS, Windows, a title run.
    AI-assisted (Claude Code).

@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.

The lifetime fix and tests are well covered: LockLiveGuestThread stays held for the attribute read, ended threads return ESRCH, and tests include joined, finished-unjoined, detached, TSD-destructor, null-input and output/errno preservation cases. The Windows focused pthread group/repeats and WSL red-green reports are detailed; unrelated GPU failures are clearly distinguished and reproduced on the main baseline. The branch/test base is a6dcea9, while current upstream main is ab347d1. Please rebase onto current main, rerun the focused guest_pthread_attr group and conventions/overlap checks, preserving the #6044 test relocation and unrelated debt edits. Hosted product jobs are skipped; I did not run local tests.

@valenciana-nc

Copy link
Copy Markdown
Contributor Author

@MarcZX10 Addressed the rebase/retest request: rebased onto b7d1d47a5f9f32c9c388ad8d47a0055a90ae6e33 (new head 6298429beb). git range-diff shows the same single-commit patch; no implementation/test changes beyond replaying it onto current main.

Windows 11 x86-64 / WinLibs GCC 15.2.0 r7 / Release / BUILD_TESTING=ON:

  • Rebuilt all 26 pthread test executables and their libkernel/libc dependencies.
  • ctest --test-dir build -R '^guest_pthread' --output-on-failure --parallel 4: 27/27 passed.
  • guest_pthread_attr --repeat until-fail:25: 25 passes.
  • New-base negative control: removed only the guard, confirmed all core/libs/prx sources match upstream/main, rebuilt and reproduced pthread_attr_get_np returned 0, expected 3. Restored the guard, rebuilt, and passed 27/27 again.
  • Conventions against synchronized origin/main, diff whitespace check, and overlap checker completed successfully. The overlap checker still has warnings, not an entirely clean report.

Manual overlap verification: #6044's combined merge-tree places this test at core/libs/tests/threads/GuestPthreadAttr.cpp, byte-for-byte identical to this PR's test; no conflict in that file (that PR still has unrelated pre-existing conflicts). Other upstream debt edits are preserved. #9684 has one documentation-only conflict because its stack-alignment entry is immediately adjacent to this PR's lifetime entry; no code/test conflict. Requested merge-order coordination on #9684, proposing this PR first and then retaining both debt updates on its rebase. No runtime dependency, and no agreed order is claimed.

Updated the description to separate these new focused results from the historical full-suite run. Full suite, title execution, Linux and macOS were not rerun by me on the rebased head. Working tree clean. Ready for another review; hosted product builds still require a maintainer's manual run.

AI-assisted execution and report.

@valenciana-nc

Copy link
Copy Markdown
Contributor Author

@MarcZX10 Follow-up audit refreshed this once more to 271d428b2d on audit-start main f57ceaad6b; range-diff confirms the same patch. Rebuilt all 26 pthread executables and their runtime dependencies: 27/27 tests and 25 attribute-test repeats passed on Windows 11/WinLibs GCC 15.2.0 r7. Removing only the guard on this new base reproduces pthread_attr_get_np returned 0, expected 3; restored/rebuilt and passed 27/27 again. Conventions and whitespace checks pass.

Rechecked #6044: the relocated test remains byte-identical; unrelated conflicts in that PR are not fixed here. #9573's created-suspended field copy composes with the lifetime guard. The #9684 author has now agreed to this PR first and to preserving both adjacent debt updates on their rebase: #9684 (comment). Description updated accordingly; no runtime dependency.

The rebase/retest review request is addressed; awaiting re-review. Full suite and Linux/macOS/title testing were not rerun on this head. AI-assisted.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants