Skip to content

Commit 8958828

Browse files
dcwhiteclaude
andcommitted
Always take _Exit on Apple instead of gating on deployment target
The version gate this replaces could not have worked. Nothing in the build sets CMAKE_OSX_DEPLOYMENT_TARGET, so __MAC_OS_X_VERSION_MIN_REQUIRED follows the build host and reads 150000 on exactly the macOS 15 builders that emit the hard _quick_exit reference. The trigger is the SDK, not the host: a macOS 14 machine with Xcode 16 installed builds the broken binary. Both spellings also fail to compile against SDKs older than 15, which do not declare quick_exit at all -- bare quick_exit as an undeclared identifier, std::quick_exit as a reference to an unresolved using declaration, since libc++'s <cstdlib> has no ::quick_exit to pull in. _Exit is equivalent here as nothing registers at_quick_exit handlers, so take it unconditionally on Apple and drop the version arithmetic entirely. Verified against the 13.3 and 15.2 SDKs: compiles on both, and nm -u shows __Exit with no _quick_exit reference. For contrast, std::quick_exit against the 15.2 SDK compiles clean and emits _quick_exit, which is the load-time failure on macOS < 15. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 190e37e commit 8958828

1 file changed

Lines changed: 21 additions & 19 deletions

File tree

src/Core/Utils/QuickExit.h

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,6 @@
3131

3232
#include <cstdlib>
3333

34-
#ifdef __APPLE__
35-
#include <Availability.h>
36-
#endif
37-
38-
/// quick_exit only entered libSystem in macOS 15.0, and the SDK declares it with no
39-
/// availability annotation ("void quick_exit(int) __dead2;" in _stdlib.h). Compiling
40-
/// against the macOS 15 SDK with an older deployment target therefore emits a hard
41-
/// reference and links cleanly with no warning, but the binary aborts on load on
42-
/// macOS < 15 with "dyld: Symbol not found: _quick_exit". Fall back to _Exit there.
43-
///
44-
/// The literal 150000 is deliberate: __MAC_15_0 is undefined on SDKs older than 15
45-
/// and would silently evaluate to 0, inverting this test.
46-
#if defined(__APPLE__) && (__MAC_OS_X_VERSION_MIN_REQUIRED < 150000)
47-
#define SCIRUN_NO_QUICK_EXIT 1
48-
#endif
49-
5034
namespace SCIRun
5135
{
5236
namespace Core
@@ -57,11 +41,29 @@ namespace Core
5741
/// regression mode to avoid hangs and crashes in async teardown paths where
5842
/// streaming execution threads outlive the GUI objects.
5943
///
60-
/// Both branches below must stay behaviorally equivalent, which holds only so long
61-
/// as nothing registers at_quick_exit handlers: _Exit does not run them.
44+
/// Apple always takes _Exit so that one build runs on every supported macOS.
45+
/// quick_exit entered libSystem in macOS 15.0, which breaks both directions:
46+
///
47+
/// - Against SDKs older than 15, it is not declared at all. Both spellings fail to
48+
/// compile -- "quick_exit" as an undeclared identifier, "std::quick_exit" as a
49+
/// reference to an unresolved using declaration, since libc++'s <cstdlib> has no
50+
/// ::quick_exit to pull in.
51+
/// - Against the 15 SDK it is declared ("void quick_exit(int) __dead2;" in
52+
/// _stdlib.h) gated only on __DARWIN_C_LEVEL/C11 -- a compile-time feature gate
53+
/// carrying no availability annotation -- so the compiler can neither warn nor
54+
/// weak-link. The object gets a hard _quick_exit reference and aborts on load on
55+
/// macOS < 15 with "dyld: Symbol not found: _quick_exit".
56+
///
57+
/// The trigger is the SDK, not the host: a macOS 14 machine with Xcode 16 installed
58+
/// builds the broken binary. Gating on __MAC_OS_X_VERSION_MIN_REQUIRED does not help
59+
/// either, because the deployment target is not pinned -- it follows the build host,
60+
/// and so reads 150000 on exactly the builders that emit the hard reference.
61+
///
62+
/// The two branches are equivalent only so long as nothing registers at_quick_exit
63+
/// handlers: _Exit does not run them.
6264
[[noreturn]] inline void quickExit(int code)
6365
{
64-
#ifdef SCIRUN_NO_QUICK_EXIT
66+
#ifdef __APPLE__
6567
std::_Exit(code);
6668
#else
6769
std::quick_exit(code);

0 commit comments

Comments
 (0)