Uploaded image for project: 'Realm Core'
  1. Realm Core
  2. RCORE-1377

Assertion failure in ClientHistory::trim_ct_history

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None

      I'm running into the following assertion failure (latest master) in one of my client reset tests: `REALM_ASSERT(n < ct_history_size());`. The stacktrace is:

       	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_13_1_2() 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::ClientHistory::trim_ct_history() Line 853	C++
       	realm-wrappers.dll!realm::sync::ClientHistory::set_oldest_bound_version(unsigned __int64 version) Line 1209	C++
       	realm-wrappers.dll!realm::DB::low_level_commit(unsigned __int64 new_version, realm::Transaction & transaction, bool commit_to_disk) Line 2163	C++
       	realm-wrappers.dll!realm::DB::do_commit(realm::Transaction & transaction, bool commit_to_disk) Line 2122	C++
       	realm-wrappers.dll!realm::Transaction::commit_and_continue_as_read(bool commit_to_disk) Line 207	C++
       	realm-wrappers.dll!realm::_impl::client_reset::perform_client_reset_diff(std::shared_ptr<realm::DB> db_local, std::shared_ptr<realm::DB> db_remote, realm::sync::SaltedFileIdent client_file_ident, realm::util::Logger & logger, realm::ClientResyncMode mode, bool recovery_is_allowed, bool * did_recover_out, realm::sync::SubscriptionStore * sub_store, realm::util::UniqueFunction<void __cdecl(__int64)> on_flx_version_complete) Line 616	C++
       	realm-wrappers.dll!realm::_impl::ClientResetOperation::finalize(realm::sync::SaltedFileIdent salted_file_ident, realm::sync::SubscriptionStore * sub_store, realm::util::UniqueFunction<void __cdecl(__int64)> on_flx_version_complete) Line 84	C++
       	realm-wrappers.dll!realm::sync::ClientImpl::Session::receive_ident_message::__l2::<lambda>() Line 2128	C++
       	realm-wrappers.dll!realm::sync::ClientImpl::Session::receive_ident_message(realm::sync::SaltedFileIdent client_file_ident) Line 2166	C++
       	realm-wrappers.dll!realm::sync::ClientImpl::Connection::receive_ident_message(unsigned __int64 session_ident, realm::sync::SaltedFileIdent client_file_ident) Line 1265	C++
       	realm-wrappers.dll!realm::_impl::ClientProtocol::parse_message_received<realm::sync::ClientImpl::Connection>(realm::sync::ClientImpl::Connection & connection, std::basic_string_view<char,std::char_traits<char>> msg_data) Line 349	C++
       	realm-wrappers.dll!realm::sync::ClientImpl::Connection::handle_message_received(const char * data, unsigned __int64 size) Line 945	C++
       	realm-wrappers.dll!realm::sync::ClientImpl::Connection::websocket_binary_message_received(const char * data, unsigned __int64 size) Line 403	C++
       	realm-wrappers.dll!realm::sync::websocket::`anonymous namespace'::EZSocketImpl::websocket_binary_message_received(const char * ptr, unsigned __int64 size) Line 79	C++
       	realm-wrappers.dll!`anonymous namespace'::WebSocket::frame_reader_loop() Line 972	C++
       	realm-wrappers.dll!`anonymous-namespace'::WebSocket::frame_reader_loop::__l2::<lambda>(std::error_code ec, unsigned __int64 __formal) Line 1019	C++
       	realm-wrappers.dll!realm::util::UniqueFunction<void __cdecl(std::error_code,unsigned __int64)>::SpecificImpl<void <lambda>(std::error_code, unsigned __int64)>::call(std::error_code && <args_0>, unsigned __int64 && <args_1>) Line 169	C++
       	realm-wrappers.dll!realm::util::UniqueFunction<void __cdecl(std::error_code,unsigned __int64)>::operator()(std::error_code <args_0>, unsigned __int64 <args_1>) Line 95	C++
       	realm-wrappers.dll!realm::sync::network::Service::AsyncOper::do_recycle_and_execute_helper<realm::util::UniqueFunction<void __cdecl(std::error_code,unsigned __int64)>,std::error_code,unsigned __int64>(bool orphaned, bool & was_recycled, realm::util::UniqueFunction<void __cdecl(std::error_code,unsigned __int64)> handler, std::error_code <args_0>, unsigned __int64 <args_1>) Line 2851	C++
       	realm-wrappers.dll!realm::sync::network::Service::AsyncOper::do_recycle_and_execute<realm::util::UniqueFunction<void __cdecl(std::error_code,unsigned __int64)>,std::error_code &,unsigned __int64 &>(bool orphaned, realm::util::UniqueFunction<void __cdecl(std::error_code,unsigned __int64)> & handler, std::error_code & <args_0>, unsigned __int64 & <args_1>) Line 2835	C++
       	realm-wrappers.dll!realm::sync::network::Service::BasicStreamOps<realm::sync::network::ssl::Stream>::BufferedReadOper<realm::util::UniqueFunction<void __cdecl(std::error_code,unsigned __int64)>>::recycle_and_execute() Line 2708	C++
       	realm-wrappers.dll!realm::sync::network::Service::Impl::execute(std::unique_ptr<realm::sync::network::Service::AsyncOper,realm::sync::network::Service::LendersOperDeleter> & lenders_ptr) Line 1639	C++
       	realm-wrappers.dll!realm::sync::network::Service::Impl::run() Line 1399	C++
       	realm-wrappers.dll!realm::sync::network::Service::run() Line 1763	C++
       	realm-wrappers.dll!realm::sync::ClientImpl::run() Line 494	C++
       	realm-wrappers.dll!realm::sync::Client::run() Line 1739	C++
       	realm-wrappers.dll!realm::_impl::SyncClient::<lambda>() Line 82	C++
       	[External Code]	
       	realm-wrappers.dll!thread_start<unsigned int (__cdecl*)(void *),1>(void * const parameter) Line 97	C++
       	[External Code]	
      

      I've attached the client logs. The test itself is as follows:

      Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      var tcs = new TaskCompletionSource<object>();
      var onBeforeTriggered = false;
      
      var (config, guid) = await GetConfigForApp(appType);
      
      config.ClientResetHandler = new RecoverOrDiscardUnsyncedChangesHandler
      {
          OnBeforeReset = GetOnBeforeHandler(tcs, beforeFrozen =>
          {
              Assert.That(onBeforeTriggered, Is.False);
      
              AssertOnObjectPair(beforeFrozen);
              onBeforeTriggered = true;
              tcs.SetResult(null);
          })
      };
      
      using var realm = await GetRealmAsync(config, waitForSync: true);
      
      realm.Write(() =>
      {
          realm.Add(new ObjectWithPartitionValue(guid)
          {
              Value = alwaysSynced,
          });
      });
      
      await WaitForUploadAsync(realm).Timeout(15_000, detail: "Wait for upload");
      var session = GetSession(realm);
      session.Stop();
      
      realm.Write(() =>
      {
          realm.Add(new ObjectWithPartitionValue(guid)
          {
              Value = maybeSynced,
          });
      });
      
      AssertOnObjectPair(realm);
      
      await TriggerClientReset(realm);
      
      await tcs.Task.Timeout(20_000, "Expected client reset");
      Assert.That(onBeforeTriggered, Is.True);
      
      var objs = realm.All<ObjectWithPartitionValue>();
      var isDiscardLocal = config.ClientResetHandler.ClientResetMode == ClientResyncMode.Discard;
      var objectsCount = isDiscardLocal ? 1 : 2;
      
      await TestHelpers.WaitForConditionAsync(() => objs.Count() == objectsCount);
      
      if (isDiscardLocal)
      {
          Assert.That(objs.Single().Value, Is.EqualTo(alwaysSynced));
      }
      else
      {
          AssertOnObjectPair(realm);
      }
      
      static void AssertOnObjectPair(Realm realm)
      {
          Assert.That(realm.All<ObjectWithPartitionValue>().ToArray().Select(o => o.Value),
              Is.EquivalentTo(new[] { alwaysSynced, maybeSynced }));
      }
      

      Interestingly enough, the test itself seems to pass - if I step through it, I get to the end, but then the sync client thread crashes. It appears to not be triggered by some action by the SDK as it happens in parallel with the execution of the test code.

      assertion.log

      (Note to self: this happens consistently in Session_ClientResetHandlers_AccessRealm_OnBeforeReset("flx",Realms.Sync.ErrorHandling.RecoverOrDiscardUnsyncedChangesHandler))

            Assignee:
            jonathan.reams@mongodb.com Jonathan Reams
            Reporter:
            nikola.irinchev@mongodb.com Nikola Irinchev
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: