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

Assertion failure in GroupWriter::backdate

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Unknown Unknown
    • None
    • Affects Version/s: None
    • Component/s: None

      Running into the following assertion (latest master) in one of my client reset tests: `REALM_ASSERT_DEBUG(!referenced)`.

      Stacktrace is as follows:

       	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::GroupWriter::backdate::__l2::<lambda>(realm::GroupWriter::FreeSpaceEntry & entry) Line 534	C++
       	realm-wrappers.dll!realm::GroupWriter::backdate() Line 565	C++
       	realm-wrappers.dll!realm::GroupWriter::write_group() Line 648	C++
       	realm-wrappers.dll!realm::DB::low_level_commit(unsigned __int64 new_version, realm::Transaction & transaction, bool commit_to_disk) Line 2187	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]	
      

      Client logs are attached. And the test is like this:

      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 onAfterTriggered = false;
      
      var (config, guid) = await GetConfigForApp(appType);
      
      config.ClientResetHandler = new RecoverOrDiscardHandler
      {
          OnAfterRecover = GetOnAfterHandler(tcs, (beforeFrozen, after) =>
          {
              Assert.That(onAfterTriggered, Is.False);
              Assert.That(beforeFrozen.All<ObjectWithPartitionValue>().ToArray().Select(o => o.Value),
                  Is.EquivalentTo(new[] { "1", "2" }));
              onAfterTriggered = true;
          })
      }
      
      using var realm = await GetRealmAsync(config, waitForSync: true);
      
      realm.Write(() =>
      {
          var a = realm.Add(new ObjectWithPartitionValue(guid)
          {
              Value = "1",
          });
      
          Console.WriteLine(a.Value);
      });
      
      await WaitForUploadAsync(realm).Timeout(20_000, detail: "Wait for upload");
      
      var session = GetSession(realm);
      session.Stop();
      
      realm.Write(() =>
      {
          realm.Add(new ObjectWithPartitionValue(guid)
          {
              Value = "2",
          });
      });
      
      await TriggerClientReset(realm);
      
      await tcs.Task.Timeout(30_000, "Expected client reset");
      Assert.That(onAfterTriggered, Is.True);
      
      await TestHelpers.WaitForConditionAsync(() => realm.All<ObjectWithPartitionValue>().Count() == 2, attempts: 300);
      
      Assert.That(realm.All<ObjectWithPartitionValue>().ToArray().Select(o => o.Value), Is.EquivalentTo(new[] { "1", "2" }));
      

      The assertion happens after await TriggerClientReset(realm) is called. Similarly to https://github.com/realm/realm-core/issues/6139, this only happens for FLX and only with the recover handler.

      assertion2.log

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

            Assignee:
            Unassigned Unassigned
            Reporter:
            nikola.irinchev@mongodb.com Nikola Irinchev
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: