Short description of the issue:
RxSwift is crashing with
Attempt to use unknown class at 0x265a091a
or
```Heap corruption detected, free list is damaged at 0x2834a4f50
* 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.
[RxSwiftHeapCorruption.zip](https://github.com/ReactiveX/RxSwift/files/3177015/RxSwiftHeapCorruption.zip)
**RxSwift/RxCocoa/RxBlocking/RxTest version/commit**
cce95dd7 Krunoslav Zaher. Fix TSAN issues. tag: 4.5.0
**Platform/Environment**
- [x] iOS
- [ ] macOS
- [ ] tvOS
- [ ] watchOS
- [ ] playgrounds
**How easy is to reproduce? (chances of successful reproduce after running the self contained code)**
- [x] easy, 100% repro
- [ ] sometimes, 10%-100%
- [ ] hard, 2% - 10%
- [ ] extremely hard, %0 - 2%
**Xcode version**:
10.2.1
**Installation method**:
- [x] CocoaPods
- [ ] Carthage
- [x] Git submodules
**I have multiple versions of Xcode installed**:
(so we can know if this is a potential cause of your issue)
- [x] 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
- [x] I have a significant code base
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.
I think we only officially support Xcode 10.2.1 with RxSwift 5. Can you check if that solves the issue? (It's still worth checking this issue, but wondering anyways).
I will try to see if it reproduces with 5.0 and Xcode 10.2.1
Issue also reproduces with RxSwift 5.0 and Xcode 10.2.1, I will update the Sample Project.
The reproduction rated decreased from 100% to 60-80%.
Edit: Sample project with RxSwift 5.0
RxSwiftHeap.Rx.5.0.zip
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.
I'm not sure why do you expect this to work. This won't work as far as I can tell or you will get sporadic crashes or issues.
Even if binary stability is in place I would be suspicious if this worked because project could have different configurations for DEBUG or RELEASE builds, or different optimisations turned on.
This might be theoretically possible if there is ABI stability, but since Xcode can't even build static libraries correctly now, I wouldn't even try.
It worked well so far, that is why I was hoping to continue to work, maybe I didn't explain clear the workflow.
Imagine that you are creating a closed source SDK, let's call it SpringSDK, which relies on RxSwift.
You distribute SpringSDK, as prebuilt dynamic framework through Cocoapods, and you specify in your podspec, that RxSwift is a dependency, you can specify an exact version so you make sure that cocoapods installs the correct RxSwift, but as long as is ABI stability shouldn't be any issue.
SpringSDK is closed source, so only the prebuilt dynamic library SpringSDK.framework is included, not also the sources, this creates the limitation that the user of your SDK, needs to use the same toolchain as the one used to build the framework.
When the user will do pod install it will install SprintSDK.framework and cocoapods automatically will resolve the dependencies and also pull the sources for RxSwift.
I do not think it is a good idea to pack all your dependencies prebuilt in your pod, along with your SDK, imagine having 10 dependencies not only 1.
In the attached sample project, I embedded the framework that uses RxSwift, as it was the simplest way to do it, for testing purpose. I cannot provide our SDK because it is not public.
@georgescumihai
Imagine that you are creating a closed source SDK, let's call it SpringSDK, which relies on RxSwift.
You distribute SpringSDK through Cocoapods, and you specify in your podspec, that RxSwift is a dependency, you can specify an exact version so you make sure that cocoapods installs the correct RxSwift.
Yes, this will probably fail. I'm not sure we can do anything on our side. This is Swift/LLVM toolchain. There is no followup action for us as far as I can tell.
If you have some suggestion, feel free to make it and we can consider it.
In the attached sample project, I embedded the framework that uses RxSwift, as it was the simplest way to do it, for testing purpose. I cannot provide our SDK because it is not public.
If it's not public, then distribute it internally as source. I can't see a happy end with this approach, but maybe you'll get lucky like you have so far. In either case, don't see any issue with this project.
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.swift
#if DEBUG
fileprivate let _synchronizationTracker = SynchronizationTracker()
#endif
In 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 when self._lock.lock() is called, it crashes with Thread 1: EXC_BAD_ACCESS (code=1, address=0x6000617ac2c0), or SIGABRT, and the console message Attempt to use unknown class or Heap 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.

If it's not public, then distribute it internally as source. I can't see a happy end with this approach, but maybe you'll get lucky like you have so far. In either case, don't see any issue with this project.
That is the thing, it is not meant to be public for our users.
Internally is distributed as sources.
For example if you look at ZendeskSDK it includes ZendeskCoreSDK which is closed source.
https://github.com/CocoaPods/Specs/blob/master/Specs/6/5/9/ZendeskSDK/2.3.1/ZendeskSDK.podspec.json
I think when he says internally he means actually copy the source (or as a submodule), and not using some dependency manager as a separate module. I'm not too experienced with your specific scenario unfortunately.
We take advantage of the dynamic linking, because we do not need to provide the dependencies with the prebuilt SDK that we distribute. Delivering the SDK as source code is not an option.
It is funny that it works with Carthage and not with Cocoapods.
Going back to the issue, we have a workaround at this point, it is ugly but works until we find a better solution.
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.
It's a warning generator in DEBUG mode. As far as I can tell this class is internal so I have no idea why should it matter. Does the Swift ABI include internal members? If it includes non public members what kind of ABI is that :)
I can sympathize with toolchain issues, but I'm not sure this is anything actionable on our end or that there is some problem with the project itself.
Will close the issue for now. Thanks.
We are facing the same issue, with the same use case
It is required to have a prebuilt binary in your project, which was build with release configuration that uses RxSwift as dependency
@georgescumihai do you build your test archive from your Mac on from a CI ?
If you are doing it from a CI, could you share your solution ?
Thank you by advance !
@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.
Any idea if this is fixed in Xcode 11/ RxSwift 5.0? I can at least say I don't see any runtime issues just yet
Facing the same issue since upgrade to XCode 11.2 / Swift 5.1.2 (didn't had this issue with XCode 10.3 / Swift 5.0).
@georgescumihai could you give more details on your workaround if possible?
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.
We were not experiencing this issue when we were build locally our SDK through carthage, but the issue was happening when we were distributing our pre built SDK through cocoapods.
So the solution was to include RxSwift as part of the prebuilt sdk.
Probably this is fixed if the build library for distribution is set to YES, but I haven't tried it yet.
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:
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == "RxSwift"
target.build_configurations.each do |config|
if config.name == "Debug"
config.build_settings['SWIFT_ACTIVE_COMPILATION_CONDITIONS'] = []
end
end
end
end
end
Still though, someone please fix this!
Is this issue fixed in any way? As I understand from this thread we have 2 workarounds:
@georgescumihai For us, setting Build Libraries for Distribution to YES didn't work.
What is the state of this issue? We're having this issue with version 4.5.0, is this fixed in version 5.0?
Thank you
We are still including RxSwift as pre-build library in our SDK.
Most helpful comment
@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.