Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift.assertionFailure call unexpectedly crashes in -O / release build when captured in singleton initializer #60249

Open
calda opened this issue Jul 26, 2022 · 7 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler itself default arguments Feature: default arguments for value parameters global let & var Feature: global constants and variables optimized only Flag: An issue whose reproduction requires optimized compilation

Comments

@calda
Copy link
Contributor

calda commented Jul 26, 2022

Describe the bug

A call to Swift.assertionFailure can unexpectedly crash in -O / release builds, when captured in a singleton initializer.

Steps To Reproduce

Build and run this sample code with -O:

final class Logger {

  init(assertionFailure: @escaping AssertionFailure = Swift.assertionFailure) {
    _assertionFailure = assertionFailure
  }

  typealias AssertionFailure = (
    _ message: @autoclosure () -> String,
    _ fileID: StaticString,
    _ line: UInt)
    -> Void

  public static var shared = Logger()

  public func assertionFailure(
    _ message: @autoclosure () -> String = String(),
    fileID: StaticString = #file,
    line: UInt = #line)
  {
    _assertionFailure(message(), fileID, line)
  }

  private let _assertionFailure: AssertionFailure

}

// This doesn't trigger a fatal error:
Logger().assertionFailure("Doesn't crash when build with -O")

// But this does:
Logger.shared.assertionFailure("Unexpectedly crashes when build with -O")

Expected behavior
Neither calls to Swift.assertionFailure should crash, since the code is build with -O.

The first call to Logger().assertionFailure doesn't crash, as expected, but the call to Logger.shared.assertionFailure does crash (despite being initialized with exactly the same arguments).

Environment (please fill out the following information)

  • Reproduces on every Swift version I've tested on, including 4.0, 5.0, 5.6, and 5.7.
@calda calda added the bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. label Jul 26, 2022
@calda
Copy link
Contributor Author

calda commented Jul 26, 2022

Changing the initializer from

init(assertionFailure: @escaping AssertionFailure = Swift.assertionFailure) {
  _assertionFailure = assertionFailure
}

to:

init(
  assertionFailure: @escaping AssertionFailure = { message, file, line in
    Swift.assertionFailure(message(), file: file, line: line)
  })
{
  _assertionFailure = assertionFailure
}

fixes the issue, but naively I would expect those two implementations to behave identically.

@kkiermasz
Copy link

Fascinating issue. Would you mind sharing what crash you get?

@calda
Copy link
Contributor Author

calda commented Jul 27, 2022

The Logger.shared.assertionFailure fatal errors with the same message in both -O release builds and -Onone debug builds: "Fatal error: Unexpectedly crashes when build with -O". The stack trace, however, is slightly different:

-O, release

#0	0x000000018c17bc08 in _swift_runtime_on_report ()
#1	0x000000018c207080 in _swift_stdlib_reportFatalErrorInFile ()
#2	0x000000018beb8c70 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) ()
#3	0x000000018beb7b34 in _assertionFailure(_:_:file:line:flags:) ()
#4	0x000000018beb7e28 in assertionFailure(_:file:line:) ()
#5	0x0000000102a49044 in Logger.assertionFailure(_:fileID:line:) [inlined] at /Users/cal/Downloads/latest/swiftfailure/LottieLogger.swift:87
#6	0x0000000102a49020 in ViewController.viewDidLoad() at /Users/cal/Downloads/latest/swiftfailure/ViewController.swift:22

-Onone, debug

#0	0x000000018c17bc08 in _swift_runtime_on_report ()
#1	0x000000018c207080 in _swift_stdlib_reportFatalErrorInFile ()
#2	0x000000018beb8c70 in closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) ()
#3	0x000000018beb7b34 in _assertionFailure(_:_:file:line:flags:) ()
#4	0x000000018beb7e28 in assertionFailure(_:file:line:) ()
#5	0x0000000100550830 in Logger.assertionFailure(_:fileID:line:) at /Users/cal/Downloads/latest/swiftfailure/LottieLogger.swift:87
#6	0x000000010054ec1c in ViewController.viewDidLoad() at /Users/cal/Downloads/latest/swiftfailure/ViewController.swift:22

Notice how the Logger.assertionFailure is marked as [inlined] in the -O stack trace but not in -Onone. Although this doesn't seem to be important, because if I add @inline(none) to the func assertionFailure in Logger then the stack traces are totally identical (no inlining) but it still behaves unexpectedly in -O.

@timoninas
Copy link

Hello, I have crush in Lottie Library

Do you mind, what can be reason of this crush?

Screenshot 2023-02-07 at 16 50 30

@AnthonyLatsis
Copy link
Collaborator

AnthonyLatsis commented Feb 10, 2023

@timoninas That is a problem with Lottie, not Swift itself. Searching the web for this failure or creating an issue in the Lottie repository might be helpful.

@AnthonyLatsis AnthonyLatsis added compiler The Swift compiler itself global let & var Feature: global constants and variables default arguments Feature: default arguments for value parameters optimized only Flag: An issue whose reproduction requires optimized compilation labels Feb 10, 2023
@TDMNS
Copy link

TDMNS commented May 25, 2023

And I have this problem when I call:

let animationView = LottieAnimationView(configuration: LottieConfiguration(renderingEngine: .specific(.coreAnimation)))

In any other case - this error is not present.

@calda
Copy link
Contributor Author

calda commented May 25, 2023

For Lottie-specific problems please file an issue on the airbnb/lottie-ios repo. This issue is specifically about the unexpected release crash of Swift.assertionFailure in the Swift compiler itself, which is unrelated to Lottie.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler itself default arguments Feature: default arguments for value parameters global let & var Feature: global constants and variables optimized only Flag: An issue whose reproduction requires optimized compilation
Projects
None yet
Development

No branches or pull requests

5 participants