Going from RealmSwift 1.1.0 to Realm 2.0.0, with a clean install of our application, we are experiencing this crash :
libc++abi.dylib: terminating with uncaught exception of type realm::SharedGroup::BadVersion: std::exception
The code where it breaks is :
template <typename T>
std::unique_ptr<T> SharedGroup::import_from_handover(std::unique_ptr<SharedGroup::Handover<T>> handover)
{
if (handover->version != get_version_of_current_transaction()) {
**throw BadVersion();**
}
std::unique_ptr<T> result = move(handover->clone);
result->apply_and_consume_patch(handover->patch, m_group);
return result;
}
Thanks for reporting! Sorry to hear you're hitting this. We'll look into it. In the meantime, can you share an Xcode project or code sample that can trigger this?
Can't send the Xcode project. Not here anyway ;)
When I run, here is the values I see:
Run 1
Run 2
Run 3
Run 4
Here is the print of Run 4 (maybe if can help)
Printing description of handover:
(std::__1::unique_ptr<realm::SharedGroup::Handover<realm::TableView>, std::__1::default_delete<realm::SharedGroup::Handover<realm::TableView> > >) handover = {
__ptr_ = {
std::__1::__libcpp_compressed_pair_imp<realm::SharedGroup::Handover<realm::TableView> *, std::__1::default_delete<realm::SharedGroup::Handover<realm::TableView> >, 2> = {
__first_ =
}
}
}
Printing description of result:
(std::__1::unique_ptr<realm::TableView, std::__1::default_delete<realm::TableView> >) result = {
__ptr_ = {
std::__1::__libcpp_compressed_pair_imp<realm::TableView *, std::__1::default_delete<realm::TableView>, 2> = {
__first_ = 0x00007fff52620068
}
}
}
+1 same exception in our project
If you have a project that reproduces this that you're willing to share privately, please feel free to email it to [email protected].
same issue
Here are some info about the issue.
The crash is only occurring on devices where big synchronisation is done. Meaning a lot of objects are created, accessed (for processing), updated,... Mostly operations added on NSOperationQueues with .UserInitiated or .Utility QOS.
Here is the full stack trace: https://www.dropbox.com/s/shpy6x51dp92blr/realm2.0.0Stack.png?dl=0
Maybe it will help solve the issue.
We tried to reproduce the crash in other projects and in a new project but since we don't know if the problem is the model, the read/write, the amount of operations,... we are a bit in the dark. Can't share the code of the project where it happens unfortunately.
Note, we also have, in the same project this issue: https://github.com/realm/realm-cocoa/issues/4143 but when a migration between 1.1.0 to 2.0.0 occurs. Don't know if it has an impact or not.
I've run into this once, and it hasn't happened since.
I take it back. Others are running into it. It seems to occur possibly only on a first launch post-Realm 2.0? I'll try and find some commonalities and possible reproduction steps.
It appears that this was fixed in realm/realm-core#2218, which we incorporated in the Objective-C/Swift projects in #4156. This is a duplicate of #4143.
I'd appreciate if you all could build from source using the latest master to confirm that this resolves the issue.
If using CocoaPods, you may build form the latest master by placing this in your Podfile:
pod 'Realm', git: 'https://github.com/realm/realm-cocoa.git', branch: 'master', submodules: true
pod 'RealmSwift', git: 'https://github.com/realm/realm-cocoa.git', branch: 'master', submodules: true
We are still having this crash. Even with the latest commits on master.
It seems related to the realm not being refreshed when it should. We are using a lot of background queues and operation queues with a lot of write transaction in each operation queues. The issue seems related to the fact that the autorefresh is not working when no runloop is available.
We modified the core of our sync process to use a realm that is not auto-updating and calling refresh() manually. It seems that it helps but we are still seeing the issue (crash) at once in a while (way less but still).
Since we don't really now when we need to call the refresh, we are adding it a bit everywhere: before and after write transactions. Will continue to add them to test.
Would love to have something done realm side instead of manually our side. Don't know why it is not done automatically, it should imho.
Note: the same code did not make any issue with Realm 1.1.0 and under. But we had a lot of issues with realm files expanding beyond expected (that's why we are compating the realm at launch to avoid crashes when mmaping). Both issues are maybe related. Would love to see Realm handle write transaction in background queues safer.
@kevincador, do you have a version of your app that reproduces this reliably? If so, would you be willing to share a precompiled IPA of that version of your app with us at [email protected] so we can attempt to reproduce the crash ourselves?
+1
It happens randomly
How can we test the fix?
Is there a way via CocoaPods?
@bdash & @tgoyne I have an app that consistently crashes with this error on startup. The crash occurs about two-thirds to three-quarters of the time. Let me know if you would like me to give [email protected] access to the repository to help troubleshoot.
tg/update-objectstore).@bdash I pulled the tg/update-objectstore branch, and am still experiencing the error. I deleted the app in simulator, deleted DerivedData, and tried it again, but still get the error 2/3 to 3/4 of the time. It seems to occur when the app is executing a lot of Realm writes. I'm running Xcode 8.0 with iPhone6s simulator running iOS 10.
EDIT to confirm the branch I am running via Cocoapods is:
pod 'RealmSwift', :git => 'https://github.com/realm/realm-cocoa.git', :branch => 'tg/update-objectstore', submodules: true
I did some tests on simulator (Xcode 8/iOS 10). It seems to be fixed for us. Just for documentation and if someone is wondering, here is the lines used in our pod file for our tests:
pod 'Realm', :git => 'https://github.com/realm/realm-cocoa.git', :branch => 'tg/update-objectstore', submodules: true
pod 'RealmSwift', :git => 'https://github.com/realm/realm-cocoa.git', :branch => 'tg/update-objectstore', submodules: true
We'll send a version to our beta testers asap to confirm it is fixed for us at a larger scale.
I'm pleased to hear your positive results with @tgoyne's fix, @kevincador.
@mlusas, can you elaborate on what you did to test?
@bdash here are the steps I used to test:
Our app does not utilize a lot of Realm writes until the User logs in. It is after logging in, and restarting the app, that the error occurs immediately upon building. It consistently crashes about 2/3 to 3/4 of the time. Let me know if I can provide any additional information to help troubleshoot.
Did you update your Podfile to point both Realm and RealmSwift at the branch, as @kevincador mentioned in his comment? Failing to do this will result in building RealmSwift against the most recently released version of Realm, which does not yet have the fix you're after.
Ah, wonderful, thank you, @bdash . I ran pod update RealmSwift with the added pod 'Realm'... line, and ran the app ten times without an error. This issues seems to be fixed.
For anyone following the thread, the updated Cocoapod lines are (post merge with master):
pod 'Realm', :git => 'https://github.com/realm/realm-cocoa.git', :branch => 'master', submodules: true
pod 'RealmSwift', :git => 'https://github.com/realm/realm-cocoa.git', :branch => 'master', submodules: true
Hey,
I still get the crash on my side, I'm using Realm 2.4.2 with iOS version 10.2 (was reproduced on simulator), here is the stuck trance in case you need it:
frame #0: 0x00000001060d9381 Augury - Dev`::__cxa_throw(void *, std::type_info *, void (*)(void *)) [inlined] _dispatch_once(block=<unavailable>) block_pointer) at once.h:67 [opt]
frame #1: 0x00000001060d9381 Augury - Dev`::__cxa_throw(exception_object=0x00006080001146b8, tinfo=0x0000000106513000, dest=(Augury - Dev`realm::LogicError::~LogicError()))(void *)) + 20 at BGSCXXException.mm:58 [opt]
* frame #2: 0x0000000105e8132c Augury - Dev`void realm::SharedGroup::advance_read<(anonymous namespace)::TransactLogValidator>(this=0x00007f84e211cc00, observer=0x0000700009570e88, version_id=(version = 8, index = 7))::TransactLogValidator*, realm::VersionID) + 220 at group_shared.hpp:938
frame #3: 0x0000000105e8123b Augury - Dev`void realm::_impl::SharedGroupFriend::advance_read<(anonymous namespace)::TransactLogValidator>(sg=0x00007f84e211cc00, obs=0x0000700009570e88, ver=(version = 8, index = 7))::TransactLogValidator*, realm::VersionID) + 59 at group_shared.hpp:1109
frame #4: 0x0000000105e6cb4b Augury - Dev`void realm::LangBindHelper::advance_read<(anonymous namespace)::TransactLogValidator>(sg=0x00007f84e211cc00, observer=0x0000700009570e88, version=(version = 8, index = 7))::TransactLogValidator&&, realm::VersionID) + 59 at lang_bind_helper.hpp:335
frame #5: 0x0000000105e6cb01 Augury - Dev`realm::_impl::transaction::advance(sg=0x00007f84e211cc00, (null)=0x0000000000000000, version=(version = 8, index = 7)) + 113 at transact_log_handler.cpp:685
frame #6: 0x0000000105bfbdc5 Augury - Dev`(anonymous namespace)::IncrementalChangeInfo::advance_to_final(this=0x00007000095716f0, version=(version = 8, index = 7)) + 117 at realm_coordinator.cpp:516
frame #7: 0x0000000105bf9c43 Augury - Dev`realm::_impl::RealmCoordinator::run_async_notifiers(this=0x00007f84e0c0f420) + 7363 at realm_coordinator.cpp:648
frame #8: 0x0000000105bf7d05 Augury - Dev`realm::_impl::RealmCoordinator::on_change(this=0x00007f84e0c0f420) + 37 at realm_coordinator.cpp:459
frame #9: 0x0000000105bad2ff Augury - Dev`realm::_impl::ExternalCommitHelper::listen(this=0x00006000000571f0) + 735 at external_commit_helper.cpp:217
frame #10: 0x0000000105bae177 Augury - Dev`realm::_impl::ExternalCommitHelper::ExternalCommitHelper(this=0x0000600000132dd0)::$_0::operator()() const + 23 at external_commit_helper.cpp:159
frame #11: 0x0000000105bae14d Augury - Dev`_ZNSt3__112__async_funcIZN5realm5_impl20ExternalCommitHelperC1ERNS2_16RealmCoordinatorEE3$_0JEE9__executeIJEEEvNS_15__tuple_indicesIJXspT_EEEE [inlined] std::__1::__invoke<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0>(__f=0x0000600000132dd0)::$_0>(fp)(std::__1::forward<>(fp0))), realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0&&) + 61 at __functional_base:416
frame #12: 0x0000000105bae13c Augury - Dev`_ZNSt3__112__async_funcIZN5realm5_impl20ExternalCommitHelperC1ERNS2_16RealmCoordinatorEE3$_0JEE9__executeIJEEEvNS_15__tuple_indicesIJXspT_EEEE(this=0x0000600000132dd0, (null)=__tuple_indices<> @ 0x0000700009572c20) + 44 at future:2348
frame #13: 0x0000000105bae105 Augury - Dev`std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0>::operator(this=0x0000600000132dd0)() + 21 at future:2341
frame #14: 0x0000000105bae02f Augury - Dev`std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::__execute(this=0x0000600000132d40) + 31 at future:1031
frame #15: 0x0000000105baeaa4 Augury - Dev`std::__1::__thread_proxy<std::__1::tuple<void (std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >*> >(void*, void*) [inlined] std::__1::__invoke<void (std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >*, void>(__f=0x00006000000330c0, __a0=0x00006000000330d0)::$_0> >*>(fp0)).*fp(std::__1::forward<>(fp1))), void (std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::*&&)(), std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >*&&) + 127 at __functional_base:383
frame #16: 0x0000000105baea25 Augury - Dev`std::__1::__thread_proxy<std::__1::tuple<void (std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >*> >(void*, void*) [inlined] _ZNSt3__116__thread_executeIMNS_19__async_assoc_stateIvNS_12__async_funcIZN5realm5_impl20ExternalCommitHelperC1ERNS4_16RealmCoordinatorEE3$_0JEEEEEFvvEJPSA_EJLm1EEEEvRNS_5tupleIJT_DpT0_EEENS_15__tuple_indicesIJXspT1_EEEE(__t=0x00006000000330c0) + 40 at thread:347
frame #17: 0x0000000105bae9fd Augury - Dev`std::__1::__thread_proxy<std::__1::tuple<void (std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >::*)(), std::__1::__async_assoc_state<void, std::__1::__async_func<realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&)::$_0> >*> >(__vp=0x00006000000330c0) + 365 at thread:357
frame #18: 0x000000010d68daab libsystem_pthread.dylib`_pthread_body + 180
frame #19: 0x000000010d68d9f7 libsystem_pthread.dylib`_pthread_start + 286
frame #20: 0x000000010d68d1fd libsystem_pthread.dylib`thread_start + 13`
@sblepa based on the backtrace, that appears to be a slightly different error, despite throwing the same exception. I've filed a new issue here so we can continue to investigate: #4660
I'm locking this ticket to prevent new reports from being missed or incompletely reported.
Most helpful comment
We are still having this crash. Even with the latest commits on master.
It seems related to the realm not being refreshed when it should. We are using a lot of background queues and operation queues with a lot of write transaction in each operation queues. The issue seems related to the fact that the autorefresh is not working when no runloop is available.
We modified the core of our sync process to use a realm that is not auto-updating and calling
refresh()manually. It seems that it helps but we are still seeing the issue (crash) at once in a while (way less but still).Since we don't really now when we need to call the refresh, we are adding it a bit everywhere: before and after write transactions. Will continue to add them to test.
Would love to have something done realm side instead of manually our side. Don't know why it is not done automatically, it should imho.
Note: the same code did not make any issue with Realm 1.1.0 and under. But we had a lot of issues with realm files expanding beyond expected (that's why we are compating the realm at launch to avoid crashes when mmaping). Both issues are maybe related. Would love to see Realm handle write transaction in background queues safer.