Skip to content

feat(libSceSystemService): restart the running title in sceSystemServiceLoadExec - #1525

Closed
emaurel wants to merge 1 commit into
boykopovar:mainfrom
emaurel:feat/system-service-load-exec
Closed

emaurel wants to merge 1 commit into
boykopovar:mainfrom
emaurel:feat/system-service-load-exec

Conversation

@emaurel

@emaurel emaurel commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

What

sceSystemServiceLoadExec("/app0/eboot.bin", argv) restarts the running title with the given arguments instead of throwing. Only "exit" was handled before.

  • The argument array is null-terminated and does not include the program name, as shadPS4 reads it (src/core/libraries/system/systemservice.cpp). The restarted title keeps the host argv[0]. Neither point is confirmed on a PS5 title; both are recorded in TechnicalDebt.
  • Any other executable still throws, because the relinker converts only the title's executable.
  • Linux: after the runtime shutdown (LibcRunShutdown), descriptors above 2 are marked close-on-exec, the signal mask and ignored signals are reset, and execv("/proc/self/exe", ...) replaces the process. The PID stays the same.
  • Windows: there is no process replacement. The new process gets an inherited SYNCHRONIZE handle to the old one, named by ANYPS5_LOAD_EXEC_PREVIOUS_PROCESS. libSceSystemService waits on it while loading, before the title runs. The old process runs the shutdown and then terminates. The two processes therefore never hold direct memory at the same time, which matters because it is committed in full (USAGE.md). Arguments are passed as UTF-8, the same encoding the entry stub uses, and are quoted by the CommandLineToArgvW rules. Arguments that are not UTF-8 throw before anything is started.

Tested

  • Windows 10 22H2 (19045), RTX 4060, WinLibs GCC 15.2.0 UCRT r7, Release, -DBUILD_TESTING=ON
  • Linux, Ubuntu 24.04 (WSL2), GCC 13.3, Release
    • The same test passed 10 times out of 10. The restarted process has the same PID. Before the restart, the old process ignores SIGPIPE and blocks SIGUSR1; the restarted process checks that both are back to their defaults.
    • Dropping an argument, skipping the shutdown, skipping the signal reset, or resetting only the mask each make it fail.
    • With --coverage, the test runs 32 of the 34 lines of the Linux half of LoadExec.cpp. The two lines not run are a pthread_sigmask failure path and the unreachable closing brace.
    • The full suite on lavapipe (Mesa 25.2.8, VK_DRIVER_FILES, GALLIUM_OVERRIDE_CPU_CAPS=avx) passes 434 of 435, with 22 GPU tests skipped. guest_video_out_wqhd_detection hit its 20 s timeout under -j4. Run alone it passes with this change, and it also timed out without it.
  • python3 tools/check_conventions.py --base upstream/main passes.
  • No title or homebrew was tested.

Checklist

  • Based on current main; no other open pull request implements the same functions (feat(libSceSystemService): implement Disable/ReenableMediaPlay #1269 also edits libSceSystemService/Export.cpp, for DisableMediaPlay/ReenableMediaPlay only)
  • 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 (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
  • AI-assisted: yes

🤖 Generated with Claude Code

…iceLoadExec

LoadExec of /app0/eboot.bin now restarts the title with the given
arguments instead of throwing. Linux replaces the process with execv
after the runtime shutdown; Windows starts the new process, which waits
for the old one to end before the title runs, so the two never hold
direct memory at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@emaurel
emaurel force-pushed the feat/system-service-load-exec branch from 10902d8 to a93116d Compare October 8, 2026 11:13

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

Solid implementation of sceSystemServiceLoadExec for title restart. The cross-platform approach (execv on Linux, CreateProcess with synchronization on Windows) is well thought out and handles the tricky aspects like signal reset, descriptor management, and process termination ordering.

Strengths:

  • Comprehensive testing covering argument passing, special characters, UTF-8 handling, and edge cases
  • Good documentation in TechnicalDebt about platform differences and unverified behavior
  • Proper synchronization to prevent both processes from holding direct memory simultaneously on Windows

Minor notes:

  1. The PR is marked as draft - appropriate given the complexity
  2. Consider whether the ANYPS5_LOAD_EXEC_PREVIOUS_PROCESS environment variable name should be documented for users who might need to debug restart issues

This looks ready to merge once CI passes and any rebase conflicts are resolved.

@emaurel
emaurel marked this pull request as ready for review October 8, 2026 11:16

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

Excellent implementation of sceSystemServiceLoadExec for title restart. This is a complex feature that requires careful handling of both Linux and Windows process models.

Strengths:

  • Clean separation into dedicated LoadExec.cpp/LoadExec.hpp files
  • Proper platform-specific implementations: execv on Linux, new process creation with inherited handle on Windows
  • Comprehensive test coverage including edge cases (quotes, backslashes, UTF-8 characters, empty arguments)
  • Good handling of signal reset and descriptor cleanup on Linux
  • Thorough documentation of limitations in TechnicalDebt.md

Technical notes:

  • The Windows approach using an inherited SYNCHRONIZE handle via environment variable is a clever solution to the lack of process replacement
  • Proper UTF-8 validation before starting the new process prevents encoding issues
  • Test cases properly verify argument passing, signal reset, and previous process termination

This will improve compatibility with titles that use sceSystemServiceLoadExec for restart functionality. Ready to merge.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Which title calls sceSystemServiceLoadExec("/app0/eboot.bin", ...) on main? This adds a lot of process handling, so it needs a title that stops there: the ID and the log line. Otherwise I'll close it until one does.

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the thorough work and the Windows/Linux test coverage. As @oneandonlydean asked, this needs a concrete title before it can go in:

  • Which title calls sceSystemServiceLoadExec("/app0/eboot.bin", ...) and stops there on main? Please add the PPSA id and the log line (the NotImplemented_nid_no_patch abort). Neither the PR body nor the linked PRs name one ("No title or homebrew was tested"), and the argument layout (no program name, null-terminated) is only taken from shadPS4, so a real call site would also confirm it.
  • Without that, the process handling added here (LoadExec.cpp, descriptor/signal reset, Windows handle hand-off) can't be justified. If no title reaches it yet, we'd rather keep the throw until one does.

Once a title is named, I'm happy to re-review.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 10, 2026
@emaurel

emaurel commented Oct 10, 2026

Copy link
Copy Markdown
Contributor Author

No title on main reaches sceSystemServiceLoadExec("/app0/eboot.bin", ...) as far as I know, so I'm closing this. I'll reopen it with the title ID and the log line if I find one.

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

Labels

build docs needs rebase Conflicts with main, rebase needed prx

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants