Skip to content

Commit f0cd714

Browse files
committed
Rework the watchOS concurrency back-deployment async frame pointer.
Introduce a few changes to the logic for watchOS concurrency back-deployment with respect to the async frame pointer. * Only apply the change to watchOS device targets, not simulator targets * Only introduce the override when no specific `-swift-async-frame-pointer=<value>` option is provided on the command line * Only override the default when deploying to watchOS < 8, and * Use "never" for the default rather than "always". This represents a different but safer trade-off than before. Setting the async bit in the frame pointer can cause older APIs (such as backtrace APIs in the OS) to crash when they encounter such frame pointers. So, with this change we never set the bit when back-deploying for watchOS device, to avoid said crashes. The trade-off here is that a back-deployed watchOS app will never have the async frame pointer bit set, so async backtraces will be unavailable even when running on watchOS 8 or newer.
1 parent 4aca32c commit f0cd714

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

lib/Frontend/CompilerInvocation.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,16 +1982,17 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
19821982
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
19831983
A->getAsString(Args), A->getValue());
19841984
}
1985+
} else if (Triple.isWatchOS() && !Triple.isSimulatorEnvironment()) {
1986+
// watchOS does not support auto async frame pointers due to bitcode, so
1987+
// silently override "auto" to "never" when back-deploying. This approach
1988+
// sacrifies async backtraces when back-deploying but prevents crashes in
1989+
// older tools that cannot handle the async frame bit in the frame pointer.
1990+
unsigned major, minor, micro;
1991+
Triple.getWatchOSVersion(major, minor, micro);
1992+
if (major < 8)
1993+
Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Never;
19851994
}
19861995

1987-
// watchOS does not support auto async frame pointers due to bitcode, so
1988-
// silently override "auto" to "always". This approach sacrifies async
1989-
// backtraces in older watchOS versions to gain better backtraces in newer
1990-
// versions.
1991-
if (Triple.isWatchOS() &&
1992-
Opts.SwiftAsyncFramePointer == SwiftAsyncFramePointerKind::Auto)
1993-
Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Always;
1994-
19951996
return false;
19961997
}
19971998

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1-
// RUN: %target-swift-frontend -disable-availability-checking -target arm64_32-apple-watchos7 %s -S | %FileCheck -check-prefix=ALWAYS %s
1+
// RUN: %target-swift-frontend -disable-availability-checking -target arm64_32-apple-watchos7 %s -S | %FileCheck -check-prefix=NEVER %s
22
// RUN: %target-swift-frontend -disable-availability-checking -target arm64_32-apple-watchos8 %s -S | %FileCheck -check-prefix=ALWAYS %s
3-
// RUN: %target-swift-frontend -disable-availability-checking -target arm64_32-apple-watchos7 -swift-async-frame-pointer=auto %s -S | %FileCheck -check-prefix=ALWAYS %s
3+
// RUN: %target-swift-frontend -disable-availability-checking -target arm64_32-apple-watchos7 -swift-async-frame-pointer=always %s -S | %FileCheck -check-prefix=ALWAYS %s
44
// RUN: %target-swift-frontend -disable-availability-checking -target arm64_32-apple-watchos7 -swift-async-frame-pointer=never %s -S | %FileCheck -check-prefix=NEVER %s
5+
// RUN: %target-swift-frontend -disable-availability-checking -target arm64_32-apple-watchos7 -swift-async-frame-pointer=auto %s -S | %FileCheck -check-prefix=AUTO %s
56

67
// REQUIRES: OS=watchos
8+
// REQUIRES: CPU=armv7k || CPU=arm64_32
79

810
public func someAsyncFunction() async {
911
}
1012

13+
// AUTO: swift_async_extendedFramePointerFlags
14+
15+
// ALWAYS-NOT: swift_async_extendedFramePointerFlags
16+
// ALWAYS: 0x1000000000000000
1117
// ALWAYS-NOT: swift_async_extendedFramePointerFlags
18+
1219
// NEVER-NOT: swift_async_extendedFramePointerFlags
20+
// NEVER-NOT: 0x1000000000000000

0 commit comments

Comments
 (0)