Repository navigation
test(agc): spawn the lazy resolved ABI reference child without a shell - #10650
maximilianfv wants to merge 2 commits into
Conversation
The lazy resolved ABI test starts its --eager-reference child through std::system, that is through /bin/sh. On macOS /bin/sh is a protected platform binary, so dyld drops every DYLD_* variable when it starts and the child inherits an environment without the path to the Vulkan loader; it then skips for lack of a Vulkan device and the parent fails with "the eager reference process failed". On hosts other than Windows, start the child with posix_spawnp and the parent's environment, and wait for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MarcZX10
left a comment
There was a problem hiding this comment.
Reviewed exact head 569e4d36da693f0ce8b949cb2c3e6df4e640f868. On POSIX, the test now launches itself directly with posix_spawnp and passes the current environ, avoiding the shell that strips DYLD_* variables under SIP; it waits for the child and requires a normal zero exit. Windows retains its prior std::system path. Exact-head diff-check, conventions, and merge-tree checks pass; hosted eligibility, conventions, intake, labels, and report pass, while product builds are skipped. I did not run the macOS GPU test locally; the validation results are the author’s controlled two-run report. No blocking issue found.
MarcZX10
left a comment
There was a problem hiding this comment.
Reviewed the complete diff at 569e4d3. On non-Windows, posix_spawnp launches the same executable directly with the existing environment and waitpid propagates the child exit code; Windows retains its existing path. This matches the repository’s existing POSIX spawn helper. The macOS cause and red/green results in the PR body are detailed and consistent with the change. Local verification: git diff --check, check_conventions.py, and the current-main merge tree pass. I could not run the macOS Vulkan test locally; hosted eligibility, conventions, intake, labels, and report checks pass, while product builds are skipped by policy. The author reports four MoltenVK image-view VUIDs in the newly reached draw phases; those lines concern untouched image-view code and should be tracked separately if no existing issue covers them. The limitation is disclosed in the PR body.
|
Windows run of Not run: a title. AI-assisted: yes (Claude Code) |
|
@maximilianfv In Could you retry |
waitpid can return -1 with EINTR when a handled signal arrives while the eager reference child is still running. The test would then fail, and its cleanup would remove the reference and cache paths the child may still be writing. Retry the wait until the child is reaped; a nonzero exit, a signalled exit and a failed spawn still report a failure. A self-check covers exit 0, a nonzero exit, a killed child, a failed spawn, and a wait interrupted by a signal sent to the waiting thread, whose handler is the only thing that lets that child exit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@oneandonlydean Done in
On the M1 Pro (MoltenVK), on mugurc's macOS series ( |
|
@maximilianfv The WaitExit loop now addresses the interrupted-wait ownership bug and keeps the exit-status failures intact. The remaining part of my ask is the regression check: as you noted, the 50 ms signal can arrive before waitpid, so Interruptions == 1 and code == 0 can both pass with a one-shot wait that never saw EINTR. Please make the check require an observed or injected EINTR before the successful reap, and show that removing the retry fails it while the corrected helper passes. Keep the exit-0, nonzero, signal and spawn-failure controls. There is no need to change the posix_spawnp/environment approach again. |
|
A Windows rerun of the new head
AI-assisted: yes (Claude Code) |
What
core/libs/prx/libSceAgcDriver/tests/execution/LazyResolvedAbi.cppstarts its--eager-referencechild withstd::system, which runs the command through/bin/sh -c. On macOS/bin/shis a SIP-protected platform binary, so dyld removes everyDYLD_*variable when it starts it. The child then losesDYLD_FALLBACK_LIBRARY_PATH, which is how the tests find the LunarG SDK'slibvulkan.1.dylib(theDYLD_LIBRARY_PATHsetup from #1 is stripped the same way). It fails withVulkan loader: Failed loading libvulkan.1.dylib. WithoutANYPS5_REQUIRE_VULKANthe child skips with "no usable Vulkan device" (exit 77,VulkanTestDevice.hpp:25-26,LazyResolvedAbi.cpp:681); with it,OpenVulkanTestDevicerethrows (VulkanTestDevice.hpp:24) and the child'smainreturns 1 (LazyResolvedAbi.cpp:723). Either way the parent stops withlazy resolved ABI: the eager reference process failed. This makesagc_driver_lazy_resolved_abiandagc_driver_lazy_resolved_abi_switch_setfail on every macOS setup that points dyld at the Vulkan loader through aDYLD_*variable; a loader installed on dyld's default search path (for example/usr/local/lib) is unaffected.On hosts other than Windows, the child now starts with
posix_spawnp(argv[0], {argv[0], "--eager-reference"}, environ)andwaitpid. That passes the parent's environment on unchanged without going through a shell, the same waycore/relinker/relinker/tests/RelinkerProcess.hppalready usesposix_spawn(..., environ). The test still requires exit status 0. Following oneandonlydean's review, the wait (WaitExit) retrieswaitpidwhile it fails withEINTR, so the test never fails, and its cleanup never deletes the reference and cache paths, while the child is still running. A nonzero exit, a signalled exit and a failed spawn still count as failures. A self-check (CheckWaitExit), run before the eager child starts, covers exit 0, exit 3, a child killed bySIGKILL, a failed spawn, and one interrupted wait. In that last case the forked child blocks on a pipe until aSIGALRMhandler, installed withoutSA_RESTARTand aimed at the waiting thread withpthread_kill, writes to it, so the child cannot exit before the signal arrives. Windows keepsstd::system. The change is limited to this test. The other self-spawning tests that usestd::system(ShaderDiskCache.cpp,AsyncLog.cpp) are left alone because their children pass without loading Vulkan.Prior art: commit 5546b23 in #8658 by @iamthehimansh (2026-10-23, closed) found the same cause in this test. It fixes it differently: it keeps
std::systemand, on macOS only, addsDYLD_LIBRARY_PATH="..."to the front of the shell command, so it passes on only that one variable (notDYLD_FALLBACK_LIBRARY_PATH). The fix was never split out of #8658, and neither #10362 nor #10419 carries it. #7201 and #7332 do not change this test.Tested
Apple M1 Pro, macOS 27.0.1, x86_64 build under Rosetta 2, Vulkan through MoltenVK from the LunarG Vulkan SDK 1.4.363.
mainalone does not build on macOS, so I built in a tree made of mugurc's macOS series (ci/macos-series-2,27e968974) merged withmainat522e32e3b6, plus these local changes, all identical in both runs: the macOS build parts of #10419, #10540, #10562, #10641, #10642, and two of my unopened fixes (the image table reuse chain-pool check, and anOpMemoryBarrierbefore 32-bit image atomics inSpirvImageEmitter.cpp). Only this PR's change was toggled. Both runs usedANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ctest --test-dir build -R '^agc_driver_lazy_resolved_abi' -E 'audio_in|voice' -V.DYLD_FALLBACK_LIBRARY_PATHexported,sh -c 'echo $DYLD_FALLBACK_LIBRARY_PATH'prints an empty line. A small C probe shows thatposix_spawnpasses the variable to the child andsystem()drops it. A wrapper that exports the variable again inside the child makes the unchanged test pass.libvulkan.1.dylib, and the parent stops withthe eager reference process failed.6 shaders drew, 5 of them ABI-resolved; ... the lazy run wrote none of the 43 shader cache files eager wrote again.was not found but was requested by env var VK_INSTANCE_LAYERS. The run without the change has 0Validation Errorlines. The run with it has 4, allVUID-VkImageViewCreateInfo-imageViewFormatReinterpretation-04466(vkCreateImageView, portability subset,imageViewFormatReinterpretationisVK_FALSEon MoltenVK). Each test logs one in the eager child's draw phase and one in the parent's lazy draw phase. Without the change, neither phase runs: the child fails while loading Vulkan, and the parent stops at the check of the child's exit status. So these errors come from image view code that this test never reached before, and this change touches no device or image code.EINTRfollow-up (1e4cc24bb5), on mugurc's macOS series (ci/macos-series-2,27e968974) merged withmainat2742004ed2, same command, 3 runs each with the previous head569e4d36daand with this head: both tests pass 2/2 in all six runs, including the new self-check. Every run has the same 4VUID-VkImageViewCreateInfo-imageViewFormatReinterpretation-04466errors and no layer-not-found line. Not checked: whether the 50 ms signal can land before the main thread reacheswaitpid. The check then still passes, but without exercising the retry.Not tested on Linux or Windows. Windows keeps the same code path, and on Linux
posix_spawnpwithenvirongives the child the same environmentstd::systemdid.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code