RxSwift: Runtime errors with Xcode 9.3 / Swift 4.1

Short description of the issue:

combineLatest/zip operators fail at runtime with latest Xcode 9.3b1 / Swift 4.1 running against iOS 11.3 OR 11.2.

Expected outcome:

combineLatest/zip operators execute without crashing.

What actually happens:

Intermittent bad access errors.

Self contained code example that reproduces the issue:

Run the iOS Test Suite with Xcode 9.3b1.

It seems disabling the tests in Observable+CombineLatestTests+arity.swift, Observable+ZipTests.swift, and Observable+ZipTests+arity.swift will allow the test suite to pass, so I assume the focus will be on the zip/combineLatest operators.

RxSwift/RxCocoa/RxBlocking/RxTest version/commit

RxSwift 4.1.1

Platform/Environment

  • iOS
  • macOS
  • tvOS
  • watchOS
  • playgrounds

How easy is to reproduce? (chances of successful reproduce after running the self contained code)

  • easy, 100% repro
  • sometimes, 10%-100%
  • hard, 2% - 10%
  • extremely hard, %0 - 2%

Xcode version:

Xcode 9.3b1

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 46 (19 by maintainers)

Most upvoted comments

I’ll give a day or two to test it out. If nobody reports any significant issues, I’ll cut a new release.

Ok, nobody reported any issues, I’ll try to merge some minor PR and cut a new release.

xcode 9.4 Swift version : “Apple Swift version 4.1.2 (swiftlang-902.0.54 clang-902.0.39.2)” so it should be fixed right?. I am also testing in the meantime.

Update : My project seems not crashing any more. xcode: 9.4 RxCocoa: 4.1.2 (So without updating Rx library) CocoaPods: 1.5.3

Just for information: Xcode 9.4 beta 2 includes Apple Swift version 4.1.1 (swiftlang-902.0.53 clang-902.0.39.2) I couldn’t reproduce the crashes above with this version.

Follow up - the issue is fixed on Swift master: https://bugs.swift.org/browse/SR-7064

Still an issue for us as well. XCode 9.3 Release version. RxCocoa 4.1.2 & RxSwift 4.1.2. Debug config works just fine. Release config 100% crash rate.

Hi @tcldr @kzaher,

Do we have any workaround for this? Facing the runtime crash on 9.3 Release version.

It seems that it’s still occurring with Xcode 9.3.1, with the example workspace linked above (https://bugs.swift.org/browse/SR-7064). The test app still crashes as detailed in the steps to reproduce.

Oh dear, what a pain. I’m not looking forward to running into more of these.

Unfortunately I don’t think this a single bug, but a whole collection of bugs introduced by the Swift 4.1 optimiser. As such, I think it’s really important that, when anyone discovers an issue you raise the issue with the Swift team via https://bugs.swift.org – it’s the only way to get them fixed.

Also, to improve the chance of the Swift team fixing the bug, it’s best to try and isolate the bug into as tidy a reproducible project as possible. In some cases you’ll be more successful than others, but the easier you make it for the Swift team to reproduce the more likely they are to fix it.

For SR-6860 that ended up being just a couple of lines of code completely outside of RxSwift. You can then place that in a swift file named, for example, MyBug.swift and run xcrun swiftc -o mybug MyBug.swift from the terminal, to see if it crashes and get the stack trace if so. Then it’s just a simple case of pasting the offending code and stack trace into your bug report as shown in SR-6860.

For SR-7064 I wasn’t able to isolate the bug from RxSwift and so it was necessary to build a workspace that demonstrated the issue in-situ. (In fact, the only way I could isolate SR-6860 was by following this method.) In this case it’s best to include a copy of the RxSwift code so that when the person working on the bug runs the project, they don’t need to jump through hoops to get RxSwift debug symbols visible in the debugger. Also, you can create an Xcode scheme in the project that applies optimisations.

The basic steps have similarities with creating an RxSwift playground:

  • Create a new Xcode workspace for you bug.
  • Download the latest Source archive from the releases tab of RxSwift (The 4.1.2 Source Archive is here for example) and add the Rx project (not workspace) to your new workspace.
  • Create a new Xcode project, drag into your workspace, link to your workspace copy of the Rx frameworks.
  • Create a scheme that compiles with optimisations and demonstrates the bug.

You can see an example by downloading the attachment with SR-7064.

When I’ve followed these steps, the bugs I’ve submitted have all been resolved within a couple of weeks.

@worthbak it’s great to link Swift bugs that affect RxSwift in this repo.

I was trying to say that we can’t do anything about those.

@tcldr Perfect write-up thnx.

Hi @tcldr ,

I’ve been contacted by Apple. I’m currently updating https://github.com/apple/swift-source-compat-suite to support swift 4.0. I’m hoping that that should help Swift compiler team.

@kzaher we were able to reduce the bug we’re seeing down to a pretty simple example. Presenting this view controller and tapping its button is a 100% crasher on Xcode 9.3 / Swift 4.1 (and RxSwift 4.1.2) with compiler optimizations set to Release ([-O]):

import UIKit
import RxSwift

class ViewController: UIViewController {
    
    private let disposeBag = DisposeBag()
    
    private let publishSubject = PublishSubject<Void>()
    private let buttonPublishSubject = PublishSubject<Void>()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        // Add button
        let button = UIButton(type: .system)
        button.frame = view.bounds
        button.setTitle("I'll crash your app.", for: .normal)
        button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
        
        view.addSubview(button)
        
        // Setup observables
        buttonPublishSubject
            .subscribe(onNext: publishSubject.onNext) // ___CRASH___
//            .bind(to: publishSubject) // using `bind` avoids the crasher
//            .subscribe(onNext: { self.publishSubject.onNext($0) }) // also does not crash
            .disposed(by: disposeBag)
        
        publishSubject
            .observeOn(MainScheduler.instance)
            .subscribe(onNext: {
                print("button tapped")
            })
            .disposed(by: disposeBag)
    }

    @objc
    func buttonTapped(_ sender: Any) {
        self.buttonPublishSubject.onNext(())
    }
}

As you can see, passing publishSubject.onNext directly to an subscribe(onNext... call seems to be the root cause of our crash. We’ve confirmed that the crash does not occur when built with Xcode 9.2, nor when compiler optimizations are set to Debug ([-Onone])

We’re not totally certain that this is the same issue seen by others in this thread, but it seems close enough that we thought we’d post it here - please let me know if you like us to open another ticket, and/or more information is needed.

@tcldr Great, good job. That’s all we can do.

Apparently back to normal!! ❤️

Hi @bobgodwinx ,

unfortunately if it does’t crash for you or me that doesn’t prove that fix entered swiftlang-902.0.48 and that those claims are false.

It’s simpler to wait for next Xcode release. It should probably be out in a week or two.

@tcldr @kzaher ditto - thanks for the writeup! I’ve created a contained workspace that include RxSwift and reproduces the bug (see attached), and will update my comment on the aforementioned Swift issue.

RxSwift_Crash-Swift_4_1.zip

It looks like using Swift compiler optimizations is an experimental feature :trollface: , ugh 😦

Hi @tcldr,

I understand why you might think that is a good idea from practical point of view, but I’m against adding and maintaining Swift compiler and UIKit regression tests inside this repo, although that is accidentally the case currently.

I’m looking at you mr. #1526.