realm / realm-kotlin

Kotlin Multiplatform and Android SDK for the Realm Mobile Database: Build Better Apps Faster.
Apache License 2.0
923 stars 56 forks source link

Native crash when run on iOS #1248

Closed tarasmorskyi-mediamonks closed 1 year ago

tarasmorskyi-mediamonks commented 1 year ago

As iOS is still not using the shared code test part wasn't maintained and now as we are moving forward everything got updated Realm from 1.0.0 to 1.6.0 and Kotlin from 1.7.10 to 1.8.0. On old versions everything runs fine with no issues, but not when running on Realm 1.1.0+ (went through try and fail to find when it stopped working) which means it's probably connected to new memory management and totally makes sense looking on assembly crash. Unfortunately I couldn't reproduce the issue on sample project so I have to roughly describe where it's crashing. It basically happens on app launch as it's data from very first request for app settings stored into Realm. Part is launched in Repo init part injected through Koin and coroutine is launched with this internal scope CoroutineScope(SupervisorJob() + Dispatchers.Default). When I do copyToRealm it's crashes with stacktrace shown on screenshots shared in comments. I've tried using some fake object thinking maybe it's Ktor doing something to coroutine state but still no.

Could you share what is happening in crashed part so I could find what is causing it?

tarasmorskyi-mediamonks commented 1 year ago

Screenshot 2023-01-27 at 14 13 39 Screenshot 2023-01-27 at 14 14 03 Screenshot 2023-01-27 at 14 14 09 Screenshot 2023-01-27 at 14 14 12 Screenshot 2023-01-27 at 14 14 15 Screenshot 2023-01-27 at 14 14 19 Screenshot 2023-01-27 at 14 14 22

clementetb commented 1 year ago

Thanks for reporting the issue. We would need more context to investigate the issue. Could you share some details about the model you are trying to write in the Realm?

Did the new memory model work on your project when you used Realm 1.0.0 and Kotlin 1.7.10? If yes, could you keep updating the Realm dependency until you find the one that breaks your IOS app?

tarasmorskyi-mediamonks commented 1 year ago

@clementetb thanks for replying.

While I was trimming all the possible fields to share it here I've found what is causing issue. It's all because of embedded objects. Here is sample project which has this issue and here is realm model

tarasmorskyi-mediamonks commented 1 year ago

I tried the repo from above again and it had a readable mistake as field is not nullable but should be. It's not the case for the actual project which means I still cannot reproduce it on small project. I pushed replication of model from actual project here

tarasmorskyi-mediamonks commented 1 year ago

reguarding the question above. Yes, new MM was in place before and only change of Realm version caused an issue.

rorbech commented 1 year ago

Hi @tarasmorskyi-mediamonks. I have tried your reproduction project and cannot reproduce the error. Can you try to elaborate on the above comments about where and when you can reproduce it?

tarasmorskyi-mediamonks commented 1 year ago

hey @rorbech , it was a false alarm and thats what I ment with my pre-last message. I have tried my shared code on empty ios project and it worked fine. I have feeling there is connection to incompatiblity with iOS libraries like RealmSwift or Lokalise. Are there any requirements on what versions are compatible to each other? I mean RealmKotlin and RealmSwift.

tarasmorskyi-mediamonks commented 1 year ago

I mention Lokalise above because I know they use Realm in Android lib so assume it's the same for iOS

rorbech commented 1 year ago

Hi @tarasmorskyi-mediamonks. We don't support running multiple SDK at the same time, so if that is what you are doing then that is probably the root of you issue. You should however be able to read a realm file written with one SDK with another SDK as long as it support the realm file format version written by both of them (the realm file format of the SDKs can be seen in the CHANGELOG). If you need more input please elaborate a bit more on your app infrastructure or make a reproduction project as it is quite hard to reason about without all the details.

tarasmorskyi-mediamonks commented 1 year ago

@rorbech what do you mean with not supporting multiple SDK at the same time? Wasn't it what fixed this issue I reported long time ago?

rorbech commented 1 year ago

@tarasmorskyi-mediamonks Yes, some things are able to coexist, but it is not guaranteed to work. We have a test for using Realm Java and Realm Kotlin simultaneous on Android in https://github.com/realm/realm-kotlin/blob/main/examples/realm-java-compatibility/app/src/androidTest/java/io/realm/kotlin/demo/javacompatibility/InstrumentedTest.kt, but we don't have similar test for Realm Swift, etc. Can you elaborate on all your Realm usage and outline a reproduction project that mimics that?

tarasmorskyi-mediamonks commented 1 year ago

@rorbech after few confusing messages (sorry) above I have a broken sample build now. Looks like issue is related to version incompatibility. As I wrote above, when I tried with actual iOS project it started braking with Realm 1.1.0 because branch I used for iOS sample was outdated and used quite old RealmSwift. Now when I have the test project it's not a problem to update Pods and I could play with versions. In the end I received that current version of RealmSwift(10.34.1) isn't compatible with current version of RealmKotlin(1.6.0). It wouldn't be a problem to drop to RealmKotlin 1.5.2 as there was nothing in Changelog I'm using, but it doesn't work with Kotlin 1.8.0 which brought quite useful things like ObjCName. I updated a repo: Broken - link Working - link

cmelchior commented 1 year ago

Hi @tarasmorskyi-mediamonks

Can you describe the exact steps to reproduce this? I tried to download your broken project, but it seems to work for me. I opened the iOS project in XCode 14.2 and ran it on iPhone 14 pro simulator.

tarasmorskyi-mediamonks commented 1 year ago

This is weird. It's exactly what I do. Everything I did is pod install and run on Iphone simulator with Xcode 14.2 as well. Could you double check if it's the branch with Kotlin 1.8.0, Realm-kotlin 1.6.0 and RealmSwift added to pods? For me just adding RealmSwift to pods while I'm on RealmKotlin 1.6.0 is breaking the app. It builds but crashes right after launch

cmelchior commented 1 year ago

@tarasmorskyi-mediamonks I noticed that there is a only a iosApp/Podfile in the working branch, but it doesn't exist in the main branch. Did you forget to commit it to main?

tarasmorskyi-mediamonks commented 1 year ago

@cmelchior main branch wasn't updated and should be ignored. Only working and broken branches should be checked and the latest one fails for me as it has RealmSwift in Pods

clementetb commented 1 year ago

We can reproduce the issue with your repo @tarasmorskyi-mediamonks. It fails as in the examples above:

EXC_BAD_ACCESS (code=1, address=0x18)

clementetb commented 1 year ago

The issue seems related to the cocoapods configuration in KMM. If you replace it with the one used in the Kotlin multiplatform demo it works fine.

I have created a PR against your demo project that shows this issue: https://github.com/tarasmorskyi-mediamonks/realm-issue-1248/pull/1

tarasmorskyi-mediamonks commented 1 year ago

@clementetb I finally had a chance to ask coworkers to try it on their machine (one on M1 one on Intel) and it works. Which means it's an issue on my machine and not with Realm. Thanks

ruicanas commented 1 year ago

@clementetb ended up finding this issue and having the same exact problem the OP was having. Tried to go use the cocoapods configuration like you said and it didn't fix it on my project. It's crashing on copyToRealm() and even the screenshots OP took reflect my problem. I'm using Kotlin 1.8.10 and Realm 1.8.0, any idea of what could it be? Also, any ideas why the cocoapods configuration could be a possible fix?

tarasmorskyi-mediamonks commented 1 year ago

@ruijfcanas the issue I had was cause by migration from Intel Macbook to M1 with Apples migration tool which copied all the installed packages no matter if there is a version for M1 already available. For me reinstalling all the iOS needed things fixed it (Xcode, Ruby, Pods whatever else, ask iOS devs)

ruicanas commented 1 year ago

@tarasmorskyi-mediamonks I have a Mac with an Intel chip and I've also tested my code on a M1 Mac and the result is the same. I did not perform any migration, so that can't be the issue on my side.

clementetb commented 1 year ago

@ruijfcanas Are you able to run any of our sample projects?

If you can run them it would mean that there is an issue in your project setup, whereas if not, it means that there is some issue in your environment.

ruicanas commented 1 year ago

@clementetb yap, the first time I succeeded but I noticed that the Kotlin version was not >=1.8.0. I then proceed to bump Kotlin version and the Realm version as well and it crashed.

❌ Screenshot with logs from Xcode ![Screenshot 2023-06-02 at 16 42 27](https://github.com/realm/realm-kotlin/assets/58333456/7c772a1c-fcaa-4e33-9fe5-3f0ad366d8c1)
❌ Screenshot with error on simulator ![Screenshot 2023-06-02 at 15 29 38](https://github.com/realm/realm-kotlin/assets/58333456/968181c3-0bc3-4f30-8d4a-91ba9fe80eb9)

Only thing I did was update the Kotlin version to 1.8.10, used the latest version for Realm and then run the project on a simulator.

EDIT 1: Forgot to mention that, on the logs, you can see that it crashed on the same method: kuntio.realm.kotlin.internal.interop.RealmInterop#realm_set_value... but now it has a different error that the one I was having on my project (and also the one OP was having)

EDIT 2: The code is working in Android with no issues. It only crashes in iOS on copyToRealm because everything else works properly, what makes me wonder if it could be some kind of issue when converting the copyToRealm code to Kotlin/Native.

ruicanas commented 1 year ago

So, I ended up finding out what the issue was. The issue was with Realm's version in my iOS app, which left me confused. I have my iOS app working with Realm, and then I have my shared module that also works with Realm. Each module handles its cache independently, so what could be the logical reason for this? Reading this post with an answer from @cmelchior has made me even more confused 😅