Skip to content

test(libSceUlt): give the ulthread runtime of the sync test its 4096 bytes - #8772

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
dantdmdarealguy:fix/ult-sync-test-runtime-size
Oct 21, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
dantdmdarealguy:fix/ult-sync-test-runtime-size

Conversation

@dantdmdarealguy

Copy link
Copy Markdown
Contributor

What

Fixes a crash in guest_ult_sync_ulthreads (added by #8248) in a Windows Debug build. On main the test dies with an access violation every time:

guest_ult_sync_ulthreads ............***Exception: SegFault  0.23 sec
FATAL: unhandled exception 0xc0000005 on thread 37744 ''
  rip 0x00007ffd7a13dec0 ucrtbase.dll+0xedec0
  write of 0x0000000821a00000
  rax 00000008219ffae0 ... rcx 0000000821a00000 ...
  stack return address candidates:
    [rsp+0x0] 0x00007ffb832356f6 libSceUlt.prx+0x56f6
    [rsp+0x80] 0x00007ff715363df3 guest_ult_sync_tests.exe+0x3df3

addr2line on the Debug binaries resolves the two return addresses to sceUltUlthreadRuntimeCreate (core/libs/prx/libSceUlt/Export.cpp:752, std::memset(runtime, 0, 4096)) and to Ulthreads (core/libs/tests/GuestUltSync.cpp:277). The test passes its 256-byte Object as the runtime, so creating the runtime writes 3840 bytes past it on the stack. In the Debug frame the object sits 0x520 bytes below the top of the main thread stack, so the write runs off the stack and faults. Release lays out the frame differently, so the overrun hits memory the test does not read afterwards, and the test passes there. That makes the bug undefined behaviour on every host, not only on Windows Debug.

The library has cleared 4096 bytes of the runtime since sceUltUlthreadRuntimeCreate was first implemented (5ae2a810e), and guest_ult_thread_tests already passes a 4096-byte Runtime (core/libs/tests/GuestUltThread.cpp:71). The change gives the sync test a 4096-byte runtime object next to its existing 512-byte UlthreadObject. The library and the other cases are unchanged.

The same overrun aborts on macOS under the stack protector; the open macOS host PR #8658 wraps a 4096-byte runtime for this test in #ifdef __APPLE__. This change fixes it for every host, so that hunk would no longer be needed.

Tested

Windows 11 Pro, Intel Core i9-14900K, 128 GB RAM, NVIDIA GeForce RTX 5080 (driver 32.0.16.1742), WinLibs GCC 15.2.0, Ninja, BUILD_TESTING=ON, every AGC execution test built.

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
  • AI-assisted: yes, some AI assistance was used

…bytes

sceUltUlthreadRuntimeCreate clears 4096 bytes of the runtime object, and guest_ult_thread_tests already passes a 4096-byte runtime. The ulthreads case of guest_ult_sync_tests passed a 256-byte object, so the runtime creation wrote 3840 bytes past it on the stack. In a Windows Debug build the write runs off the top of the main thread stack and the test crashes with an access violation.

@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 runtime buffer contract against sceUltUlthreadRuntimeCreate and the existing guest_ult_thread_tests fixture: the runtime object needs 4096 writable bytes, and this focused test supplied only 256. The 4096-byte aligned wrapper is the narrow fix, with the reported Debug red/green runs and full-suite caveats stated clearly. Eligibility, conventions and intake checks pass.

@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 test now gives sceUltUlthreadRuntimeCreate a 4096-byte, 8-byte-aligned object, matching the runtime size the implementation clears. The PR is narrowly scoped and the eligibility, conventions, intake, and labels checks pass. Build jobs are skipped for this test-only PR, so this approval is based on source inspection and those checks.

@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 8658 core/libs/tests/GuestUltSync.cpp L275-276

@oneandonlydean
oneandonlydean merged commit 1ebd80b into boykopovar:main Oct 21, 2026
10 checks passed
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.

3 participants