realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.28k stars 2.14k forks source link

EXC_BAD_ACCESS in RLMGetThreadLocalCachedRealmForPath #7741

Open bprinsta opened 2 years ago

bprinsta commented 2 years ago

How frequently does the bug occur?

Sometimes

Description

The app is seeing crashes due to an EXC_BAD_ACCESS "Attempted to deference null pointer in" RLMGetThreadLocalCachedRealmForPath when attempting to lock the realm cache mutex.

RLMRealmUtil:L58

RLMRealm *RLMGetThreadLocalCachedRealmForPath(std::string const& path, void *key) {
    std::lock_guard<std::mutex> lock(s_realmCacheMutex);

This is specifically happening on iOS 14 devices.

Stacktrace & log output

2   BananaApp   
__mutex_base:91:27
lock_guard
3   BananaApp   
RLMRealm.mm:429:35
+[RLMRealm realmWithConfiguration:queue:error:]
4   BananaApp   
BaseService.swift:21:29
one-time initialization function for realm
8   BananaApp   
BaseService.swift:21:16
static BaseService.dataMergedWithExisting(metadata:key:data:)

Can you reproduce the bug?

Not yet

Reproduction Steps

No response

Version

10.24.1

What SDK flavour are you using?

Local Database only

Are you using encryption?

No, not using encryption

Platform OS and version(s)

iOS 14 (14.0-14.8.1)

Build environment

Xcode version: 13.2 Dependency manager and version: Cocoapods

bprinsta commented 2 years ago

At this point in the debugging process, I'm not sure if this an issue with Realm or with how Realm is configured in my application, so I'd like to better understand what could cause an exception to be thrown here?

tgoyne commented 2 years ago

Is this possibly happening while the app is in the process of exiting? That line of code is a very mundane of a static variable, which means that it could fail if it's happening while or after the exit-time destructors run to tear down global variables.

If it's not something along those lines, then either the reported crash location is incorrect or something has previously gone very wrong and this is just the point where it finally results in a crash.

bprinsta commented 2 years ago

Would the destructors be called when creating a new Realm in a closure? Since our user object can be accessed on any thread, we have a singleton where we retrieve it like so:

var user: User? {
        get {
            do {
                return try Realm(configuration: BaseService.realmConfiguration).object(ofType: User.self, forPrimaryKey: userId)
            } catch {
               ...
                return nil
            }
        }

Otherwise, the app itself doesn't seem to be in the process of exiting when the crash occurs.

tgoyne commented 2 years ago

No, the mutex's lifetime is from when the first time the function is called until app shutdown.

kondratyevdev commented 2 years ago

Do you have any updates here?

dianaafanador3 commented 2 years ago

Hi @kondratyevdev are you experiencing the same crash, can you attached a more detailed stacktrace?

kondratyevdev commented 2 years ago

@dianaafanador3

Why it happens I cannot understand :( I tried to create and work with Ream only in one thread, but it didn't help.

- [ ] > Thread 14 Crashed:
- [ ] > 0   libsystem_pthread.dylib         0x00000001e4a1e744 _pthread_mutex_fairshare_unlock + 104 (pthread_mutex.c:1031)
- [ ] > 1   libc++.1.dylib                  0x00000001ad962af4 std::__1::mutex::lock() + 16 (__threading_support:397)
- [ ] > 2   FaceAppAssets                   0x0000000103befc54 lock_guard + 8 (__mutex_base:91)
- [ ] > 3   FaceAppAssets                   0x0000000103befc54 lock_guard + 8 (__mutex_base:91)
- [ ] > 4   FaceAppAssets                   0x0000000103befc54 RLMGetThreadLocalCachedRealmForPath(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void*) + 44 (RLMRealmUtil.mm:58)
- [ ] > 5   FaceAppAssets                   0x0000000103be8594 +[RLMRealm realmWithConfiguration:queue:error:] + 256 (RLMRealm.mm:429)
dianaafanador3 commented 2 years ago

As @tgoyne mentioned above, because the mutex is and static variable, this can only happen if the app is exiting which means the mutex is deallocated, before running your code. Can you reproduce it?, Can you please paste the complete stack trace for this? Or explain the particularly use case for this crash.

darkesfang commented 2 years ago

Hi @dianaafanador3, Same issue here. This happened in AppDelegate didFinishLaunchingWithOptions, we init a Realm instance in the background queue and use file coordinator to get something from the DB. This crash happened repeatedly on some iOS 14 users at the first second of a session. Sadly I still can't reproduce this, below is the stack trace.

Crashed: com.apple.root.default-qos
0  libsystem_pthread.dylib        0x7744 pthread_mutex_lock + 102
1  libc++.1.dylib                 0x3caf4 std::__1::mutex::lock() + 16
2  Realm                          0xd5988 RLMGetThreadLocalCachedRealmForPath(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void*) + 59 (RLMRealmUtil.mm:59)
3  Realm                          0xce4b8 +[RLMRealm realmWithConfiguration:queue:error:] + 394 (RLMRealm.mm:394)
4  RealmSwift                     0x40870 Realm.init(configuration:queue:) + 4402759792 (<compiler-generated>:4402759792)
5  WhoscallProduction             0x4754c closure #1 in closure #1 in PersonalBlockingDBHelper.getEntryCount() + 347 (PersonalBlockingDBHelper.swift:347)
6  WhoscallProduction             0x21c378 thunk for @callee_guaranteed () -> (@error @owned Error) + 4372906872 (<compiler-generated>:4372906872)
7  WhoscallProduction             0x48830 partial apply for thunk for @callee_guaranteed () -> (@error @owned Error) + 4370991152 (<compiler-generated>:4370991152)
8  WhoscallProduction             0x48ea4 thunk for @callee_guaranteed () -> (@error @owned Error)partial apply + 4370992804
9  libswiftObjectiveC.dylib       0x1f24 autoreleasepool<A>(invoking:) + 64
10 WhoscallProduction             0x48d50 partial apply for closure #1 in PersonalBlockingDBHelper.getEntryCount() + 4370992464
11 WhoscallProduction             0x1d83c0 thunk for @callee_guaranteed (@in_guaranteed URL) -> () + 4372628416 (<compiler-generated>:4372628416)
12 WhoscallProduction             0x1d8444 thunk for @escaping @callee_guaranteed (@in_guaranteed URL) -> () + 4372628548 (<compiler-generated>:4372628548)
13 Foundation                     0x61780 -[NSFileCoordinator _invokeAccessor:thenCompletionHandler:] + 100
14 Foundation                     0x1e0308 __73-[NSFileCoordinator coordinateWritingItemAtURL:options:error:byAccessor:]_block_invoke + 132
15 Foundation                     0x1e1808 __85-[NSFileCoordinator(NSPrivate) _coordinateWritingItemAtURL:options:error:byAccessor:]_block_invoke.350 + 268
16 Foundation                     0x61a58 -[NSFileCoordinator(NSPrivate) _withAccessArbiter:invokeAccessor:orDont:andRelinquishAccessClaim:] + 620
17 Foundation                     0x63cc0 -[NSFileCoordinator(NSPrivate) _coordinateWritingItemAtURL:options:error:byAccessor:] + 784
18 Foundation                     0x63988 -[NSFileCoordinator coordinateWritingItemAtURL:options:error:byAccessor:] + 120
19 WhoscallProduction             0x473e8 PersonalBlockingDBHelper.getEntryCount() + 344 (PersonalBlockingDBHelper.swift:344)
20 WhoscallProduction             0x136e64 closure #1 in AppDelegate.updateUserProperties() + 639 (AppDelegate.swift:639)
21 WhoscallProduction             0x23d7c8 thunk for @escaping @callee_guaranteed () -> () + 4373043144 (<compiler-generated>:4373043144)
22 libdispatch.dylib              0x2a54 _dispatch_call_block_and_release + 32
23 libdispatch.dylib              0x47ec _dispatch_client_callout + 20
24 libdispatch.dylib              0x7938 _dispatch_queue_override_invoke + 756
25 libdispatch.dylib              0x15fb0 _dispatch_root_queue_drain + 388
26 libdispatch.dylib              0x167a8 _dispatch_worker_thread2 + 112
27 libsystem_pthread.dylib        0x3768 _pthread_wqthread + 216
28 libsystem_pthread.dylib        0xa74c start_wqthread + 8
fermoyadrop commented 2 years ago

same here. Any news or workarounds to the issue? I experience the same:

kondratyevdev commented 2 years ago

Any news?

fangmobile commented 2 years ago

same here with same line and similar stack trace

fangmobile commented 2 years ago

We found we changed RealmSwift version from 10.22.0 to 10.25.1, right after this change and release, this crash started. before this change there was 0 crash related to this. Hope this info might be helpful?

bartjacobs commented 2 years ago

Like @fangmobile and @fermoyadrop, we are seeing this crash only on launch and only on iOS 14. We haven't been able to reproduce the issue.

koneksa-sunny commented 2 years ago

We are seeing a similar crash.

0   libsystem_pthread.dylib         0x00000001d43fa22c pthread_mutex_lock$VARIANT$armv81 + 0
1   libc++.1.dylib                  0x00000001a00279b8 std::__1::mutex::lock+ 244152 () + 12
2   XXXXXXXXX                0x0000000105bf7820 RLMGetThreadLocalCachedRealmForPath(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void*) + 1980448 (RLMRealmUtil.mm:59)
3   XXXXXXXXX                0x0000000105bf00c0 +[RLMRealm realmWithConfiguration:queue:error:] + 1949888 (RLMRealm.mm:429)
4   XXXXXXXXX                0x0000000105c82ae8 Realm.init(configuration:queue:) + 2550504 (Realm.swift:92)
dianaafanador3 commented 2 years ago

HI @koneksa-sunny are you trying to access the realm from AppDelegate.didFinishLaunchingWithOptions, are you using a different thread to access the realm?

PavelKandratsyeu commented 2 years ago

FYI: the issue stopped to reproduce for us when we switched back to the legacy build system in older xcode.

koneksa-sunny commented 2 years ago

HI @koneksa-sunny are you trying to access the realm from AppDelegate.didFinishLaunchingWithOptions, are you using a different thread to access the realm?

@dianaafanador3 I am accessing Realm in AppDelegate.didFinishLaunchingWithOptions on the Main thread. The code has not changed in 2+ years.

kondratyevdev commented 2 years ago

Any news on this?

bmalumphy commented 2 years ago

This is something we've encountered as well. Only an iOS 14 bug. Updating the OS is not an option for most of our users without IT support, so a workaround at least would be nice.

mnmaki commented 2 years ago

Any news on this?

thegreenline commented 1 year ago

Same her. iOS 14 only, no reproduction, no code changes in my realm conf since long time, last version 10.30.0

weibel commented 1 year ago

Same here. iOS14 only. This started when we upgraded from 10.13.0 to 10.28.5

LeffelMania commented 1 year ago

Seeing the same as described here since updating RealmSwift from 10.29.0 to 10.32.2 last week.

rex-remind101 commented 1 year ago

Same crash, function crashing at line 59 of RLMGetThreadLocalCachedRealmForPath https://github.com/realm/realm-swift/blob/9f7a605dfcf6a60e019a296dc8d91c3b23837a82/Realm/RLMRealmUtil.mm#L59 with EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000.... null ptr

RLMGetThreadLocalCachedRealmForPath(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void*) + 59

must be either s_realmsPerPath, path, or key.

s_realmsPerPath - https://github.com/realm/realm-swift/blob/9f7a605dfcf6a60e019a296dc8d91c3b23837a82/Realm/RLMRealmUtil.mm#L39 looks globally instantiated and has not changed in 3 years. unlikely to be the culprit.

key appears to originate from https://github.com/realm/realm-swift/blob/28c488974f544c9affc4eacdd5b9dfc6785ebbc0/Realm/RLMRealm.mm#L465 which appears like a safe operation, however it was changed in this pr here from just 7 months ago https://github.com/realm/realm-swift/pull/7789/files#diff-a98a6c3989e1668cf28dbcb829199452024a880dced23fc11060ba13b113989dR443

This doesn't explain occurrences before may 10th however.

may 4th this change occurred in the same vicinity https://github.com/realm/realm-swift/pull/7778/files#diff-a98a6c3989e1668cf28dbcb829199452024a880dced23fc11060ba13b113989dR409

so it appears that near that timeframe a lot of adjustments were being made in relation to the code that's crashing. Still haven't found evidence of what may have caused this in april but i suspect someone at realm could put together the pieces from here.

rex-remind101 commented 1 year ago

Interesting, did not notice this at first, OP reported line 58, but myself and some previous folks reported line 59, possibly these are 2 different crashes.

https://github.com/realm/realm-swift/issues/7741#issuecomment-1119317472 https://github.com/realm/realm-swift/issues/7741#issuecomment-1171563125

bb-git commented 1 year ago

We're seeing the same crash. iOS 14 only. We upgraded from 10.11.0 to 10.32.2 Does anyone now if only migrated users or only new or all users are affected by this? Would be interesing if it can be fixed by reinstalling the app. Simulator is working fine.

bb-git commented 1 year ago

Can this be related to cocoapods? We couldn't upgrade to a version later than 10.11.0 as it crashed on iOS 12 devices, but this issue was occurring with cocoapods only.

bb-git commented 1 year ago

So far 100% of the iOS 14 users seeing this crash, are new users. None of them was migrating from a previous installation.

bb-git commented 1 year ago

Ok, we can confirm again: only new users are affected. Also we released a version using realm with SPM instead of cocoapods and the crash doesn't happen there.

bryancaragay commented 1 year ago

Checking in to see if there's been any movement / updates for this - it's one of our largest crashes so even a workaround would be helpful @dianaafanador3

leemaguire commented 1 year ago

Hi @bryancaragay Could you post your stack traces here? Also could you try use Realm via SPM instead of Cocoapods if you are using that and see that helps?

bryancaragay commented 1 year ago

@leemaguire We're seeing the same stack trace as above, also this comment from Rex describes what we're seeing more in-depth.

Crashed: com.apple.main-thread
0  libsystem_pthread.dylib        0x775c pthread_mutex_lock
1  libc++.1.dylib                 0x400e4 std::__1::mutex::lock()
2  Realm                          0x12decc RLMGetThreadLocalCachedRealmForPath(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, void*) + 59 (RLMRealmUtil.mm:59)
3  Realm                          0x126008 +[RLMRealm realmWithConfiguration:queue:error:] + 430 (RLMRealm.mm:430)
4  RealmSwift                     0x6f70c @nonobjc RLMRealm.__allocating_init(configuration:queue:) + 72 (<compiler-generated>:72)
5  RealmSwift                     0x6fc1c Realm.init(configuration:queue:) + 95 (Realm.swift:95)