Skip to content

Commit b0b4cb6

Browse files
committed
Make asyncMainDrainQueue noreturn
CFRunLoopRun returns once it finishes, though the kernel may clean us up before we get there. We effectively have a race condition between the kernel cleaning us up and returning from a never returning function. Small programs likely get cleaned up before reaching the ud2 instruction emitted after the never returning function in swift, so they don't notice, but programs of a sufficient size do. At that size, the program will crash after what the programmer expects to be the end of their program.
1 parent 129fca6 commit b0b4cb6

File tree

2 files changed

+6
-3
lines changed

2 files changed

+6
-3
lines changed

include/swift/Runtime/Concurrency.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ void swift_continuation_logFailedCheck(const char *message);
541541
/// If the binary links CoreFoundation, uses CFRunLoopRun
542542
/// Otherwise it uses dispatchMain.
543543
SWIFT_EXPORT_FROM(swift_Concurrency) SWIFT_CC(swift)
544-
void swift_task_asyncMainDrainQueue();
544+
void swift_task_asyncMainDrainQueue [[noreturn]]();
545545

546546
/// Establish that the current thread is running as the given
547547
/// executor, then run a job.

stdlib/public/Concurrency/Task.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ void swift::swift_task_asyncMainDrainQueue() {
744744
abort();
745745

746746
pfndispatch_main();
747+
exit(0);
747748
#else
748749
// CFRunLoop is not available on non-Darwin targets. Foundation has an
749750
// implementation, but CoreFoundation is not meant to be exposed. We can only
@@ -752,8 +753,10 @@ void swift::swift_task_asyncMainDrainQueue() {
752753
#if defined(__APPLE__)
753754
auto runLoop =
754755
reinterpret_cast<void (*)(void)>(dlsym(RTLD_DEFAULT, "CFRunLoopRun"));
755-
if (runLoop)
756-
return runLoop();
756+
if (runLoop) {
757+
runLoop();
758+
exit(0);
759+
}
757760
#endif
758761

759762
dispatch_main();

0 commit comments

Comments
 (0)