-
Type: Bug
-
Resolution: Unresolved
-
Priority: Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: Sync
-
?
-
6052
-
Not Needed
This is a bit vague, but we've seen assertion failures pointing to the sync client destructor:
I've been able to reduce it as much as possible and it seems to be happening when we open a Realm, then immediately close it and tear down the app and the user. This may be causing a race condition with the sync client starting up, but that's pure speculation. Here's the stacktrace of an example crash like that
<details><summary>Stacktrace</summary>
> realm-wrappers.dll!issue_debug_notification(const wchar_t * const message) Line 28 C++ realm-wrappers.dll!__acrt_report_runtime_error(const wchar_t * message) Line 154 C++ realm-wrappers.dll!abort() Line 61 C++ realm-wrappers.dll!please_report_this_issue_in_github_realm_realm_core_v_12_12_0() Line 65 C++ realm-wrappers.dll!realm::util::terminate_internal(std::basic_stringstream<char,std::char_traits<char>,std::allocator<char>> & ss) Line 142 C++ realm-wrappers.dll!realm::util::terminate(const char * message, const char * file, long line, std::initializer_list<realm::util::Printable> && values) Line 152 C++ realm-wrappers.dll!realm::sync::ClientImpl::~ClientImpl() Line 400 C++ [External Code] realm-wrappers.dll!realm::sync::Client::~Client() Line 1694 C++ realm-wrappers.dll!realm::_impl::SyncClient::~SyncClient() Line 133 C++ [External Code] realm-wrappers.dll!realm::SyncManager::~SyncManager() Line 523 C++ [External Code] realm-wrappers.dll!realm::app::App::~App() Line 254 C++ [External Code] realm-wrappers.dll!_execute_onexit_table::__l2::<lambda>() Line 206 C++ realm-wrappers.dll!__crt_seh_guarded_call<int>::operator()<void <lambda>(void),int <lambda>(void) &,void <lambda>(void)>(__acrt_lock_and_call::__l2::void <lambda>(void) && setup, _execute_onexit_table::__l2::int <lambda>(void) & action, __acrt_lock_and_call::__l2::void <lambda>(void) && cleanup) Line 204 C++ realm-wrappers.dll!__acrt_lock_and_call<int <lambda>(void)>(const __acrt_lock_id lock_id, _execute_onexit_table::__l2::int <lambda>(void) && action) Line 980 C++ realm-wrappers.dll!_execute_onexit_table(_onexit_table_t * table) Line 231 C++ realm-wrappers.dll!common_exit::__l2::<lambda>() Line 226 C++ realm-wrappers.dll!__crt_seh_guarded_call<void>::operator()<void <lambda>(void),void <lambda>(void) &,void <lambda>(void)>(__acrt_lock_and_call::__l2::void <lambda>(void) && setup, common_exit::__l2::void <lambda>(void) & action, __acrt_lock_and_call::__l2::void <lambda>(void) && cleanup) Line 224 C++ realm-wrappers.dll!__acrt_lock_and_call<void <lambda>(void)>(const __acrt_lock_id lock_id, common_exit::__l2::void <lambda>(void) && action) Line 980 C++ realm-wrappers.dll!common_exit(const int return_code, const _crt_exit_cleanup_mode cleanup_mode, const _crt_exit_return_mode return_mode) Line 259 C++ realm-wrappers.dll!_cexit() Line 314 C++ [External Code]
</details>
The test code is:
var app = App.Create(SyncTestHelpers.GetAppConfig(AppConfigType.FlexibleSync)); var user = await GetUserAsync(app); var config = new FlexibleSyncConfiguration(user, optionalPath) { SessionStopPolicy = SessionStopPolicy.Immediately; }; using var realm = GetRealm(config);
After the test completes, we execute a cleanup step which does:
Realm.DeleteRealm(config); app.Handle.ResetForTesting();
The implementation of ResetForTesting is here: https://github.com/realm/realm-dotnet/blob/89fd0b8d48064887c40893f062715dfb861f3cdd/wrappers/src/app_cs.cpp#L315-L338
I've also captured debug level logs from the test run, but those don't seem super interesting:
<details><summary>Logs</summary>
2022-11-21 22:50:54.315 Info: Start of test 2022-11-21 22:50:54.730 Debug: App: register_email: realm_tests_do_autoverify-3b967b6c-e185-4fdb-b6eb-315da2b980cb 2022-11-21 22:50:55.093 Debug: App: update_hostname: https://realm-qa.mongodb.com | wss://realm-qa.mongodb.com 2022-11-21 22:50:55.258 Debug: App: log_in_with_credentials: app_id: flx-rider4-cluster005-kjypt 2022-11-21 22:50:55.259 Debug: App: version info: platform: Realm .NET version: Realm .NET - sdk version: 10.18.0 - core version: 12.12.0 2022-11-21 22:50:55.445 Debug: App: do_authenticated_request: GET https://realm-qa.mongodb.com/api/client/v2.0/auth/profile 2022-11-21 22:50:55.786 Debug: Realm sync client ([realm-core-12.12.0]) 2022-11-21 22:50:55.787 Debug: Supported protocol versions: 2-7 2022-11-21 22:50:55.788 Debug: Platform: Windows Win32 unknown 10.0.19041.2251 x86_64 2022-11-21 22:50:55.788 Debug: Build mode: Debug 2022-11-21 22:50:55.789 Debug: Config param: one_connection_per_session = true 2022-11-21 22:50:55.790 Debug: Config param: connect_timeout = 120000 ms 2022-11-21 22:50:55.791 Debug: Config param: connection_linger_time = 30000 ms 2022-11-21 22:50:55.792 Debug: Config param: ping_keepalive_period = 60000 ms 2022-11-21 22:50:55.792 Debug: Config param: pong_keepalive_timeout = 120000 ms 2022-11-21 22:50:55.793 Debug: Config param: fast_reconnect_limit = 60000 ms 2022-11-21 22:50:55.794 Debug: Config param: disable_upload_compaction = false 2022-11-21 22:50:55.795 Debug: Config param: disable_sync_to_disk = false 2022-11-21 22:50:55.796 Debug: User agent string: 'RealmSync/12.12.0 (Windows Win32 unknown 10.0.19041.2251 x86_64) ' 2022-11-21 22:50:55.836 Info: Test complete 2022-11-21 22:50:55.841 Detail: Connection[1]: Session[1]: Binding 'C:\Users\irinc\AppData\Local\Temp\rt-sync-91040-0\mongodb-realm\flx-rider4-cluster005-kjypt\637c00cf0abf8c8ed5592655\default.realm' to '' 2022-11-21 22:50:55.882 Debug: Connection[1]: Session[1]: Activating 2022-11-21 22:50:55.884 Info: Connection[1]: Session[1]: client_reset_config = false, Realm exists = true, client reset = false 2022-11-21 22:50:55.885 Debug: Connection[1]: Session[1]: client_file_ident = 0, client_file_ident_salt = 0 2022-11-21 22:50:55.885 Debug: Connection[1]: Session[1]: last_version_available = 6 2022-11-21 22:50:55.886 Info: Tear down, closing sessions 2022-11-21 22:50:55.887 Debug: Connection[1]: Session[1]: progress_server_version = 0 2022-11-21 22:50:55.888 Debug: Connection[1]: Session[1]: progress_client_version = 0 2022-11-21 22:50:55.889 Debug: Connection[1]: Session[1]: Progress handler called, downloaded = 0, downloadable(total) = 0, uploaded = 0, uploadable = 1784, reliable_download_progress = false, snapshot version = 6 2022-11-21 22:50:55.891 Debug: Connection[1]: Session[1]: Progress handler called, downloaded = 0, downloadable(total) = 0, uploaded = 0, uploadable = 1784, reliable_download_progress = false, snapshot version = 6 2022-11-21 22:50:55.929 Debug: Connection[1]: Session[1]: Progress handler called, downloaded = 0, downloadable(total) = 0, uploaded = 0, uploadable = 1784, reliable_download_progress = false, snapshot version = 6 2022-11-21 22:50:55.959 Debug: Connection[1]: Session[1]: Initiating deactivation 2022-11-21 22:50:55.960 Debug: Connection[1]: Session[1]: Deactivation completed 2022-11-21 22:50:55.963 Debug: Connection[1]: Destroying connection object 2022-11-21 22:50:56.130 Info: Tear down, reset for testing
</details>
If I introduce an artificial delay of 1s before we call the test teardown, it makes the issue much harder to reproduce - I've only seen it once out of ~50 attempts on my computer.