Skip to content

fix(libc): end the process without detach routines in _Exit on Windows - #2

Closed
AlxcBTW wants to merge 1 commit into
mainfrom
fix/windows-immediate-exit
Closed

AlxcBTW wants to merge 1 commit into
mainfrom
fix/windows-immediate-exit

Conversation

@AlxcBTW

@AlxcBTW AlxcBTW commented Oct 10, 2026

Copy link
Copy Markdown
Owner

What

On Windows std::_Exit ends in ExitProcess, which still runs every module's DLL_PROCESS_DETACH and TLS/FLS callbacks after the other threads are gone. A static destructor that joins a worker then waits forever. PPSA99050 (ps5-homebrew-ui) calls _Exit(EXIT_FAILURE) from ps5-opengl's retirement fail-stop; the process stays alive with one thread in std::_Sp_counted_ptr_inplace<FlipQueue>::_M_dispose (libSceVideoOut.prx) → std::thread::join → WaitForMultipleObjects (gdb stack of the hung process).

_Exit (libc) and _exit (libkernel) now end the process through LibcTerminate_nid_no_patch, which calls TerminateProcess on Windows and std::_Exit elsewhere: no atexit handlers, stream flushes or module destructors, as _exit ends a POSIX process.

Tested

Windows 11, WinLibs GCC 15.2.0 r7.

  • guest_immediate_exit now also registers an FLS callback that would end the process with 4: without the change it exits with 4, with it 0.
  • ctest -R "exit|kill": 11/11 passed; ctest -R "kill|exit|process|shutdown|atexit|libc|kernel": 19/19 passed.
  • PPSA99050 (ps5-homebrew-ui) with its import PRs merged locally: before, the process stayed alive after submission retirement failed; now it exits with 1 (EXIT_FAILURE) after the fail-stop.

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 in TechnicalDebt
  • No notes, investigation .md files or images added to the repository
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes (Claude Code)

On Windows std::_Exit ends in ExitProcess, which still runs every module's
DLL_PROCESS_DETACH and TLS callbacks after the other threads are gone. A
static destructor that joins a worker then waits forever: a title that calls
_Exit while libSceVideoOut's flip queue runs (ps5-opengl's retirement
fail-stop) stays alive in FlipQueue's destructor. _Exit and libkernel's _exit
now terminate the process with TerminateProcess, as _exit ends a POSIX
process: no atexit handlers, stream flushes or module destructors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@AlxcBTW

AlxcBTW commented Oct 10, 2026

Copy link
Copy Markdown
Owner Author

Merged upstream as boykopovar#2612.

@AlxcBTW AlxcBTW closed this Oct 10, 2026
@AlxcBTW
AlxcBTW deleted the fix/windows-immediate-exit branch October 10, 2026 11:22
AlxcBTW pushed a commit that referenced this pull request Oct 12, 2026
pr_overlap only skipped a pair when one pull request named the other
directly. In a stack where #3 depends on #2 and #2 on #1, #1 and #3 were
reported as overlapping, and two pull requests built on the same #1 were
reported for the files and exports both inherit from it. Dependencies are
now followed through open pull requests, and what a shared dependency adds
is left out of the same-file and same-export columns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0189deyapHNNqKQJboZBJQei
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant