RxSwift: Heap corruption and Attempt to use unknown class
Short description of the issue:
RxSwift is crashing with
Attempt to use unknown class at 0x265a091a
or
*** Incorrect guard value: 10770528256
RxSwiftIssue(25384,0x100cbef80) malloc: *** set a breakpoint in malloc_error_break to debug
With Xcode 10.2.1 and RxSwift 4.5.0 installed through cocoapods or source files directly, not carthage.
It doesn’t reproduces with Xcode 10.1
It is required to have a prebuilt binary in your project, which was build with release configuration that uses RxSwift as dependency, if you do not have this, it won’t reproduce.
Embed the prebuilt framework in your project. Install RxSwift (source files, or cocoapods)
Use the functionality of the prebuild binary framework that uses RxSwift.
Expected outcome: The functionality works as expected and you do not have any crash.
What actually happens:
RxSwift crashes with Attempt to use unknown class at 0x265a091a
or Heap corruption
.
Self contained code example that reproduces the issue: I attached a sample project that reproduces the issue. As well as the code for the prebuilt binary.
Just download the sample project Build the sample framework.
cd SampleFramework
carthage bootstrap --platform iOS
open SampleFramework.xcodeproj
Build the scheme SampleProjectAggregate
This scheme will create the prebuilt binary that uses RxSwift at SampleFramework/build
Setup RxSwift sample project
cd ../RxSwiftIssue/
pod install
open RxSwiftIssue.xcworkspace
Make sure you embed SampleFramework.framework
in RxSwiftIssue
app.
Run the RxSwiftIssue app Tap start on the first screen. Tap start on the second screen. And you should have a crash, if not, retry by tapping stop and start.
RxSwift/RxCocoa/RxBlocking/RxTest version/commit
cce95dd7 Krunoslav Zaher. Fix TSAN issues. tag: 4.5.0
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:
10.2.1
Installation method:
- CocoaPods
- Carthage
- Git submodules
I have multiple versions of Xcode installed: (so we can know if this is a potential cause of your issue)
- yes (which ones) Xcode 10.1.
- no
Level of RxSwift knowledge: (this is so we can understand your level of knowledge and formulate the response in an appropriate manner)
- just starting
- I have a small code base
- I have a significant code base
###### Workaround
If you replace the occurrence of `#if DEBUG` with a different flag which is not present when you build for debug, for example replace it with `#if FORCE_DEBUG`, you won't get the crash.
To get the crash you just to enable the code for `fileprivate let _synchronizationTracker = SynchronizationTracker()` in `PublishSubject.swift` and `Rx.swift`.
Carthage builds the project with configuration Release, therefore that code is not part of the framework that carthage produces.
But when you build it with cocoapods or as a submodule it will have the DEBUG flag.
Wich enables the `SynchronizationTracker` for the subjects.
Which I think causes the crash.
If you will use the SampleProject.framework sources directly in RxSwiftIssue project instead of the prebuilt binaries, it won't trigger the crash.
Our use case is a bit more complex, we distribute prebuilt binaries through cocoapods, that have as dependency RxSwift 4.5. Still the SampleProject is more or less the same idea.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 8
- Comments: 23 (5 by maintainers)
We pull RxSwift as a dependency via CocoaPods and I ran into this exact same issue. As a workaround, I added the following snippet in our Podfile:
Still though, someone please fix this!
@DamienBallenghien we are using a CI that builds our SDK based on a hook. Some of our frameworks have RxSwift as a dependency in Link Binary with Frameworks. After everything is built, we have a script that copies RxSwift together with our frameworks. We release our SDK through cocoapods specs and we add RxSwift in the subspesc.vendored_frameworks together with our frameworks.
We are still including RxSwift as pre-build library in our SDK.
you can replace
DEBUG
by anything else, the idea is to disable the rule.to “fix” it, when we build a debug build on our CI we do:
#if DEBUG
by#if FORCE_DEBUG
in files AsyncSubject.swift, PublishSubject.swift, BehaviorSubject.swift, ReplaySubject.swift, Create.swift, Sink.swiftWe are not using Swift 5.1.2 yet, I don’t know if our project would work without the script.
In this case the issues are coming from this class
final class SynchronizationTracker
, which is available when you build for debug. Mainly when it is used in Subjects, like in PublishSubject.swiftIn order to make RxSwift not to crash, I just made sure that this is not available when I build for debug. I only changed the flag, from
#if DEBUG
to#if FORCE_DEBUG
, I do not understand entirely why this is causing the crash, most of the times is crashing whenself._lock.lock()
is called, it crashes withThread 1: EXC_BAD_ACCESS (code=1, address=0x6000617ac2c0)
, or SIGABRT, and the console messageAttempt to use unknown class
orHeap corruption
.I do not know what is the purpose of
_synchronizationTracker
and why it is crashing from it, I was hopping that you guys might have an idea.