Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue using Realm with Swift Actors #7901

Open
brenmcnamara opened this issue Aug 1, 2022 · 9 comments
Open

Issue using Realm with Swift Actors #7901

brenmcnamara opened this issue Aug 1, 2022 · 9 comments

Comments

@brenmcnamara
Copy link

How frequently does the bug occur?

Sometimes

Description

We are receiving a number of crashes in our production application (1000+ crashes). These crashes began happening after we upgraded from Realm 10.20.0 to 10.28.1. In our latest release, we have reverted back to Realm 10.20.0 and these crashes have stopped happening. We are having a hard time diagnosing what is causing the crash and cannot reproduce these locally, but the stack traces we see in Crashlytics indicate that they are happening in realm::util::terminate calls (including stack traces below). Some things we are observing:

  • Crashes happen during app startup + Realm initialization process (within 5 seconds of the user opening the app)
  • There are a few common stack traces we see in the crash reports. What they all have in common is the realm::util::terminate call which is throwing the error.

Stacktrace & log output

--- CRASH 1: ---

Crashed: com.apple.main-thread
0  libsystem_kernel.dylib         0x7b38 __pthread_kill
1  libsystem_pthread.dylib        0x73bc pthread_kill
2  libsystem_c.dylib              0x20524 abort
3  Superhuman                     0x139fc24 realm::util::terminate(char const*, char const*, long, std::initializer_list<realm::util::Printable>&&)
4  Superhuman                     0x139ff0c realm::util::terminate_internal(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
5  Superhuman                     0x139fd6c realm::util::terminate(char const*, char const*, long, std::initializer_list<realm::util::Printable>&&)
6  Superhuman                     0x12ee9a8 realm::StringData realm::Obj::_get<realm::StringData>(realm::ColKey::Idx) const
7  Superhuman                     0xf4d03c objc_object* (anonymous namespace)::getBoxed<realm::StringData>(RLMObjectBase*, unsigned long) + 106 (RLMAccessor.mm:106)
8  Foundation                     0x28444 -[NSObject(NSKeyValueCoding) valueForKey:]
9  Superhuman                     0xf9dad0 -[RLMObjectBase valueForKey:] + 194 (RLMObjectBase.mm:194)
10 Superhuman                     0xf9d928 RLMValidatedValueForProperty + 531 (RLMObjectBase.mm:531)
11 Superhuman                     0xf9d05c RLMInitializeWithValue + 169 (RLMObjectBase.mm:169)
12 Superhuman                     0x10e0294 RealmSwiftObject.init(value:) (<compiler-generated>)

--- CRASH 2: ---

Crashed: com.apple.root.user-initiated-qos.cooperative
0  libsystem_kernel.dylib         0x7200 __pthread_kill
1  libsystem_pthread.dylib        0x71ac pthread_kill
2  libsystem_c.dylib              0x20e74 abort
3  Superhuman                     0x139fc24 realm::util::terminate(char const*, char const*, long, std::initializer_list<realm::util::Printable>&&)
4  Superhuman                     0x139ff0c realm::util::terminate_internal(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
5  Superhuman                     0x139fd6c realm::util::terminate(char const*, char const*, long, std::initializer_list<realm::util::Printable>&&)
6  Superhuman                     0x1278cb8 realm::Cluster::init(realm::MemRef)
7  Superhuman                     0x12866f8 realm::ClusterNodeInner::try_get(realm::ObjKey, realm::ClusterNode::State&) const
8  Superhuman                     0x1289f14 realm::ClusterTree::try_get(realm::ObjKey) const
9  Superhuman                     0x14ae0bc realm::TableView::try_get_object(unsigned long) const
10 Superhuman                     0x14a528c realm::util::Optional<realm::Obj> realm::Results::try_get<realm::Obj>(unsigned long)
11 Superhuman                     0x14a5520 realm::util::Optional<realm::Obj> realm::Results::first<realm::Obj>()
12 Superhuman                     0x1077020 RLMAccessorContext realm::Results::dispatch<auto realm::Results::first<RLMAccessorContext>(RLMAccessorContext&)::'lambda'(RLMAccessorContext&)>(RLMAccessorContext&) const + 404 (optional.hpp:404)
13 Superhuman                     0x1076e70 auto realm::Results::first<RLMAccessorContext>(RLMAccessorContext&) + 423 (results.hpp:423)
14 Superhuman                     0x1074c74 -[RLMResults firstObject] + 248 (RLMResults.mm:248)
15 Superhuman                     0x1107ff4 RealmCollectionImpl.first.getter
16 Superhuman                     0x1107f3c protocol witness for RealmCollection.first.getter in conformance LinkingObjects<A> (<compiler-generated>)

--- CRASH 3: ---

Crashed: realmWrite
0   libsystem_kernel.dylib         0x7b38 __pthread_kill
1   libsystem_pthread.dylib        0x73bc pthread_kill
2   libsystem_c.dylib              0x20524 abort
3   Superhuman                     0x139fc24 realm::util::terminate(char const*, char const*, long, std::initializer_list<realm::util::Printable>&&)
4   Superhuman                     0x139ff0c realm::util::terminate_internal(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
5   Superhuman                     0x139fd6c realm::util::terminate(char const*, char const*, long, std::initializer_list<realm::util::Printable>&&)
6   Superhuman                     0xfcbcb0 std::__1::__vector_base<double, std::__1::allocator<double> >::__throw_length_error() const + 396 (vector:396)
7   Superhuman                     0x12ea26c realm::Node::calc_item_count(unsigned long, unsigned long) const
8   Superhuman                     0x12ea2c0 realm::Node::alloc(unsigned long, unsigned long)
9   Superhuman                     0x125dbcc realm::Array::alloc(unsigned long, unsigned long)
10  Superhuman                     0x125e0f8 realm::Array::insert(unsigned long, long long)
11  Superhuman                     0x127de4c void realm::Cluster::do_insert_row<realm::ArrayBoolNull>(unsigned long, realm::ColKey, realm::Mixed, bool)
12  Superhuman                     0x127d818 realm::util::FunctionRef<bool (realm::ColKey)>::FunctionRef<realm::Cluster::insert_row(unsigned long, realm::ObjKey, realm::FieldValues const&)::$_1&>(realm::Cluster::insert_row(unsigned long, realm::ObjKey, realm::FieldValues const&)::$_1&)::'lambda'(void*, realm::ColKey)::__invoke(void*, realm::ColKey)
13  Superhuman                     0x137a02c realm::TableClusterTree::for_each_and_every_column(realm::util::FunctionRef<bool (realm::ColKey)>) const
14  Superhuman                     0x1279018 realm::Cluster::insert_row(unsigned long, realm::ObjKey, realm::FieldValues const&)
15  Superhuman                     0x127b108 realm::Cluster::insert(realm::ObjKey, realm::FieldValues const&, realm::ClusterNode::State&)
16  Superhuman                     0x128afa4 realm::ClusterNodeInner::insert(realm::ObjKey, realm::FieldValues const&, realm::ClusterNode::State&)::$_1::operator()(realm::ClusterNode*, realm::ClusterNodeInner::ChildInfo&) const
17  Superhuman                     0x1286470 realm::ClusterNodeInner::insert(realm::ObjKey, realm::FieldValues const&, realm::ClusterNode::State&)
18  Superhuman                     0x1289bb4 realm::ClusterTree::insert_fast(realm::ObjKey, realm::FieldValues const&, realm::ClusterNode::State&)
19  Superhuman                     0x1289e1c realm::ClusterTree::insert(realm::ObjKey, realm::FieldValues const&)
20  Superhuman                     0x1379dc0 realm::TableClusterTree::insert(realm::ObjKey, realm::FieldValues const&)
21  Superhuman                     0x136e378 realm::Table::create_object_with_primary_key(realm::Mixed const&, realm::FieldValues&&, realm::Table::UpdateMode, bool*)
22  Superhuman                     0xf5a9e0 realm::Table::create_object_with_primary_key(realm::Mixed const&, bool*) + 485 (vector:485)
23  Superhuman                     0xf4fea0 realm::Object realm::Object::create<objc_object* __strong, RLMAccessorContext>(RLMAccessorContext&, std::__1::shared_ptr<realm::Realm> const&, realm::ObjectSchema const&, objc_object* __strong, realm::CreatePolicy, realm::ObjKey, realm::Obj*) + 305 (object_accessor.hpp:305)
24  Superhuman                     0xf4f844 RLMAccessorContext::createObject(objc_object*, realm::CreatePolicy, bool, realm::ObjKey) + 1102 (RLMAccessor.mm:1102)
25  Superhuman                     0xfa5814 RLMAddObjectToRealm + 120 (RLMObjectStore.mm:120)
26  Superhuman                     0x10fe150 Realm.add<A>(_:update:) (<compiler-generated>)

Can you reproduce the bug?

Not yet

Reproduction Steps

No response

Version

10.28.1

What SDK flavour are you using?

Local Database only

Are you using encryption?

No, not using encryption

Platform OS and version(s)

iOS 15, iOS 16, iPadOS 15

Build environment

Xcode version: 13.4.1
Dependency manager and version: Cocoapods Version 1.11.3, Realm Version 10.28.1

@leemaguire
Copy link
Contributor

Hi @brenmcnamara Could you show us code samples of how you are using Realm at the crash site? Also some details about your object schema would be helpful.

@sync-by-unito sync-by-unito bot added the Waiting-For-Reporter Waiting for more information from the reporter before we can proceed label Aug 2, 2022
@t-sakhuja
Copy link

t-sakhuja commented Aug 17, 2022

Brendan's teammate filling in here.

We initially thought rolling back to 10.20.0 had resolved these crashes, but that appears to not be the case. Instead, we're seeing a similar volume of similar looking crashes. All of these crashes occur within a few seconds of app launch. Here are some examples:

Crash 1

Crashed: com.apple.main-thread
0  libsystem_kernel.dylib         0x7b38 __pthread_kill + 8
1  libsystem_pthread.dylib        0x73bc pthread_kill + 268
2  libsystem_c.dylib              0x20524 abort + 168
3  Superhuman                     0x13ad9b4 std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char) + 203528
4  Superhuman                     0x13adb24 realm::util::terminate_internal(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) + 203896
5  Superhuman                     0x13adc9c realm::util::terminate(char const*, char const*, long, std::initializer_list<realm::util::Printable>&&) + 204272
6  Superhuman                     0xf57a48 realm::util::do_encryption_read_barrier(void const*, unsigned long, unsigned long (*)(char const*), realm::util::EncryptedFileMapping*) + 131 (file_mapper.hpp:131)
7  Superhuman                     0x13001d8 long long realm::Obj::_get<long long>(realm::ColKey::Idx) const + 2452

Crash 2

Crashed: realmWrite
0   libsystem_kernel.dylib         0x7b38 __pthread_kill + 8
1   libsystem_pthread.dylib        0x73bc pthread_kill + 268
2   libsystem_c.dylib              0x20524 abort + 168
3   Superhuman                     0x13ad9b4 std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char) + 203528
4   Superhuman                     0x13adb24 realm::util::terminate_internal(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) + 203896
5   Superhuman                     0x13adc9c realm::util::terminate(char const*, char const*, long, std::initializer_list<realm::util::Printable>&&) + 204272
6   Superhuman                     0x125a1d8 realm::ArrayBacklink::remove(unsigned long, realm::ObjKey) + 3012
7   Superhuman                     0x13050fc realm::Obj::remove_one_backlink(realm::ColKey, realm::ObjKey) + 22712
8   Superhuman                     0x1306398 realm::Obj::remove_backlink(realm::ColKey, realm::ObjLink, realm::CascadeState&) const + 27476
9   Superhuman                     0x1302d10 realm::Obj::replace_backlink(realm::ColKey, realm::ObjLink, realm::ObjLink, realm::CascadeState&) const + 13516
10  Superhuman                     0x12ab728 realm::Lst<realm::ObjKey>::do_set(unsigned long, realm::ObjKey) + 428
11  Superhuman                     0x12ac00c realm::Lst<realm::ObjKey>::do_clear() + 848
12  Superhuman                     0x12abd08 realm::Lst<realm::ObjKey>::clear() + 76
13  Superhuman                     0xfa4b70 realm::LnkLst::clear() + 374 (vector:374)
14  Superhuman                     0xf5e510 void realm::List::assign<objc_object* __strong&, RLMAccessorContext>(RLMAccessorContext&, objc_object* __strong&, realm::CreatePolicy) + 270 (list.hpp:270)
15  Superhuman                     0xf5d83c void realm::Object::set_property_value_impl<objc_object* __strong, RLMAccessorContext>(RLMAccessorContext&, realm::Property const&, objc_object* __strong, realm::CreatePolicy, bool) + 303 (unique_ptr.h:303)
16  Superhuman                     0xf5583c realm::Object realm::Object::create<objc_object* __strong, RLMAccessorContext>(RLMAccessorContext&, std::__1::shared_ptr<realm::Realm> const&, realm::ObjectSchema const&, objc_object* __strong, realm::CreatePolicy, realm::ObjKey, realm::Obj*) + 355 (object_accessor.hpp:355)
17  Superhuman                     0xf54fbc RLMAccessorContext::createObject(objc_object*, realm::CreatePolicy, bool, realm::ObjKey) + 1093 (RLMAccessor.mm:1093)
18  Superhuman                     0xf58fcc auto realm::switch_on_type<realm::Obj, void realm::List::add<objc_object* __strong&, RLMAccessorContext>(RLMAccessorContext&, objc_object* __strong&, realm::CreatePolicy)::'lambda'(objc_object* __strong&)>(realm::PropertyType, RLMAccessorContext&&) + 1125 (RLMAccessor.mm:1125)
19  Superhuman                     0xf58aa8 void realm::List::add<objc_object* __strong&, RLMAccessorContext>(RLMAccessorContext&, objc_object* __strong&, realm::CreatePolicy) + 198 (list.hpp:198)
20  Superhuman                     0xf5e7e0 void RLMStatelessAccessorContext::enumerate_collection<void realm::List::assign<objc_object* __strong&, RLMAccessorContext>(RLMAccessorContext&, objc_object* __strong&, realm::CreatePolicy)::'lambda'(objc_object* __strong&)>(objc_object*, objc_object* __strong&) + 274 (list.hpp:274)
21  Superhuman                     0xf5e540 void realm::List::assign<objc_object* __strong&, RLMAccessorContext>(RLMAccessorContext&, objc_object* __strong&, realm::CreatePolicy) + 281 (list.hpp:281)
22  Superhuman                     0xf5d83c void realm::Object::set_property_value_impl<objc_object* __strong, RLMAccessorContext>(RLMAccessorContext&, realm::Property const&, objc_object* __strong, realm::CreatePolicy, bool) + 303 (unique_ptr.h:303)
23  Superhuman                     0xf5583c realm::Object realm::Object::create<objc_object* __strong, RLMAccessorContext>(RLMAccessorContext&, std::__1::shared_ptr<realm::Realm> const&, realm::ObjectSchema const&, objc_object* __strong, realm::CreatePolicy, realm::ObjKey, realm::Obj*) + 355 (object_accessor.hpp:355)
24  Superhuman                     0xf54fbc RLMAccessorContext::createObject(objc_object*, realm::CreatePolicy, bool, realm::ObjKey) + 1093 (RLMAccessor.mm:1093)
25  Superhuman                     0xf9f0ec RLMAddObjectToRealm + 139 (RLMObjectStore.mm:139)

Because these crashes continued after we reverted to 10.20.0 and are significantly higher in volume than before we upgraded to 10.28.1, my theory is that 10.28.1 somehow caused corruption in an elevated percentage of users' databases. All reads and writes to Realm in our codebase are serially executed on a dedicated reader or writer Actor.

@brenmcnamara
Copy link
Author

Thanks @t-sakhuja for providing the details above.

@github-actions github-actions bot added Needs-Attention Reporter has responded. Review comment. and removed Waiting-For-Reporter Waiting for more information from the reporter before we can proceed labels Aug 22, 2022
@leemaguire
Copy link
Contributor

@t-sakhuja can you show us the Actor which coordinates the reads and writes?

@sync-by-unito sync-by-unito bot added Waiting-For-Reporter Waiting for more information from the reporter before we can proceed and removed Needs-Attention Reporter has responded. Review comment. labels Aug 25, 2022
@t-sakhuja
Copy link

@leemaguire here you go

@globalActor
enum RealmReadActor {
    actor InnerRealmReadActor {}
    static let shared = InnerRealmReadActor()
}

@globalActor
enum RealmWriteActor {
    actor InnerRealmWriteActor {}
    static let shared = InnerRealmWriteActor()
}

@RealmReadActor
func readUserRealm<T>(_ userInfo: UserInfo, _ block: @RealmReadActor @Sendable (Realm) throws -> T) throws -> T {
    try autoreleasepool {
        let realm = try Realm(configuration: Realm.configurationForUser(userInfo.email))
        defer { realm.invalidate() }
        return try block(realm)
    }
}

@RealmWriteActor
func writeUserRealm<T>(_ userInfo: UserInfo, _ block: @RealmWriteActor @Sendable (Realm) throws -> T) throws -> T {
    try autoreleasepool {
        let realm = try Realm(configuration: Realm.configurationForUser(userInfo.email))
        defer { realm.invalidate() }
        return try realm.write {
            try block(realm)
        }
    }
}

/// Allow MainActor to open realms
extension Realm {
    @MainActor
    static func realmForUser(_ userInfo: UserInfo) throws -> Realm {
        return try Realm(configuration: Realm.configurationForUser(userInfo.email))
    }
}

@mr-grey
Copy link

mr-grey commented Sep 23, 2022

same crash at 1 second
Operating system
Version:16.0.0
pod 'RealmSwift', '~>10.28.2'

Crashed: com.apple.root.default-qos
0  libsystem_kernel.dylib         0x7200 __pthread_kill + 8
1  libsystem_pthread.dylib        0x71ac pthread_kill + 268
2  libsystem_c.dylib              0x20ca0 abort + 180
3  Realm                          0x2cc99c realm::util::terminate(char const*, char const*, long, std::initializer_list<realm::util::Printable>&&) + 10
4  Realm                          0x2ccc84 realm::util::terminate_internal(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char>>&) + 260
5  Realm                          0x2ccae4 realm::util::terminate(char const*, char const*, long, std::initializer_list<realm::util::Printable>&&) + 328
6  Realm                          0x15f78c realm::ArraySmallBlobs::create_array(unsigned long, realm::Allocator&, realm::BinaryData) + 54
7  Realm                          0x15f69c realm::ArraySmallBlobs::get(char const*, unsigned long, realm::Allocator&) + 532
8  Realm                          0x1f0e4c realm::StringData realm::Obj::_get<realm::StringData>(realm::ColKey::Idx) const + 668
9  Realm                          0x8414 objc_object* (anonymous namespace)::getBoxed<realm::StringData>(RLMObjectBase*, unsigned long) + 106 (RLMAccessor.mm:106)
10 RealmSwift                     0xf9b4 protocol witness for static _Persistable._rlmGetProperty(_:_:) in conformance String + 217 (BasicTypes.swift:217)
11 RealmSwift                     0x5bed4 Persisted.get(_:) + 182 (PersistedProperty.swift:182)
12 RealmSwift                     0x5bc20 static Persisted.subscript.getter + 126 (PersistedProperty.swift:126)

@leemaguire leemaguire changed the title realm::util::terminate crashes Issue using Realm with Swift Actors Sep 27, 2022
@brenmcnamara
Copy link
Author

Confirming we are still seeing the issue, currently preventing us from updating Realm.

@github-actions github-actions bot added Needs-Attention Reporter has responded. Review comment. and removed Waiting-For-Reporter Waiting for more information from the reporter before we can proceed labels Oct 7, 2022
@sync-by-unito sync-by-unito bot removed the Needs-Attention Reporter has responded. Review comment. label Oct 21, 2022
@brenmcnamara
Copy link
Author

Following up here. We are a few versions behind on Realm at this point, and are looking to upgrade, but this bug here is blocking us from upgrading to the latest version of Realm.

Could these crashes have been caused by the problem fixed in this PR?

@csamprajan
Copy link

Facing this issue in V10.38.

Screenshot 2023-04-02 at 12 43 23 PM

@sync-by-unito sync-by-unito bot removed the T-Bug label Sep 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants