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

Rare Crash on iOS (SIGBUS) in realm::Group::do_get_table(realm::StringData, bool (*)(realm::Spec const&))

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

      We get a strange crash in Realm on iOS when our App is brought into foreground sometimes. Most of the time there is no problem. The function we use is very straight forward, and is called very often without any issue.

          static func getContestLastSyncVersion(contestId: String) -> Single<Int> {
              return Single.deferred {
                  let realm = try Realm.tryCreate()
                  // next line will crash on very rare occasions
                  let items = realm.objects(CacheContest.self).filter("id == %@", contestId)
                  return Single.just(items.first?.contestMessages.max(ofProperty: "syncVersion") ?? 0)
              }
          }
      

      The stack trace suggests that the crash happens in _platform_memcmp called by realm::Group::do_get_table. Our Code is labeled "Hanako" in the stack trace.

      MAIN THREAD - CRASHED
      libsystem_platform.dylib   _platform_memcmp
      Realm    realm::Group::do_get_table(realm::StringData, bool (*)(realm::Spec const&))
      Realm    realm::ObjectStore::table_for_object_type(realm::Group&, realm::StringData) group.hpp:939
      Realm    (anonymous namespace)::get_table(realm::Group&, RLMObjectSchema*) RLMQueryUtil.mm:206
      Realm    RLMPredicateToQuery(NSPredicate*, RLMObjectSchema*, RLMSchema*, realm::Group&) RLMQueryUtil.mm:1474
      Realm    -[RLMResults objectsWithPredicate:] RLMResults.mm:361
      RealmSwift    function signature specialization <Arg[0] = Exploded> of RealmSwift.Results.filter(Swift.String, Any...) -> RealmSwift.Results<A> Results.swift:211
      Hanako    closure #1 () throws -> RxSwift.PrimitiveSequence<RxSwift.SingleTrait, Swift.Int> in static Hanako.ContestCacheImpl.getContestLastSyncVersion(contestId: Swift.String) -> RxSwift.PrimitiveSequence<RxSwift.SingleTrait, Swift.Int> ContestCacheImpl.swift:220
      Hanako    partial apply forwarder for closure #1 () throws -> RxSwift.PrimitiveSequence<RxSwift.SingleTrait, Swift.Int> in static Hanako.ContestCacheImpl.getContestLastSyncVersion(contestId: Swift.String) -> RxSwift.PrimitiveSequence<RxSwift.SingleTrait, Swift.Int> <compiler-generated>:0
      RxSwift   partial apply forwarder for closure #1 () throws -> RxSwift.Observable<B> in static RxSwift.PrimitiveSequence.deferred(() throws -> RxSwift.PrimitiveSequence<A, B>) -> RxSwift.PrimitiveSequence<A, B> PrimitiveSequence.swift:69
      RxSwift   partial apply forwarder for reabstraction thunk helper <A where A: RxSwift.ObservableType> from @escaping @callee_guaranteed () -> (@owned RxSwift.Observable<A.E>, @error @owned Swift.Error) to @escaping @callee_guaranteed () -> (@out RxSwift.Observable<A.E>, @error @owned Swift.Error) <compiler-generated>:0
      RxSwift   RxSwift.(DeferredSink in _9A640CB28D6420293D75F113534DFAC6).run() -> RxSwift.Disposable Deferred.swift:36
      RxSwift   RxSwift.(Deferred in _9A640CB28D6420293D75F113534DFAC6).run<A where A1: RxSwift.ObserverType, A.E == A1.E>(_: A1, cancel: RxSwift.Cancelable) -> (sink: RxSwift.Disposable, subscription: RxSwift.Disposable) Deferred.swift:71
      RxSwift   RxSwift.Producer.subscribe<A where A == A1.E, A1: RxSwift.ObserverType>(A1) -> RxSwift.Disposable Producer.swift:18
      RxSwift   RxSwift.(MergeSink in _DDEA0423368B3B462AE46699A4D080E1).run(RxSwift.Observable<A>) -> RxSwift.Disposable Merge.swift:507
      RxSwift   merged RxSwift.(FlatMap in _DDEA0423368B3B462AE46699A4D080E1).run<A where A1: RxSwift.ObserverType, B.E == A1.E>(_: A1, cancel: RxSwift.Cancelable) -> (sink: RxSwift.Disposable, subscription: RxSwift.Disposable)
      RxSwift   closure #1 (()) -> RxSwift.Disposable in RxSwift.Producer.subscribe<A where A == A1.E, A1: RxSwift.ObserverType>(A1) -> RxSwift.Disposable Producer.swift:26
      RxSwift   function signature specialization <Arg[2] = [Closure Propagated : reabstraction thunk helper from @escaping @callee_guaranteed () -> (@out RxSwift.Disposable) to @escaping @callee_guaranteed (@in_guaranteed ()) -> (@out RxSwift.Disposable), Argument Types : [@escaping @callee_guaranteed () -> (@out RxSwift.Disposable)]> of generic specialization <()> of RxSwift.CurrentThreadScheduler.schedule<A>(_: A, action: (A) -> RxSwift.Disposable) -> RxSwift.Disposable <compiler-generated>:0
      RxSwift   RxSwift.Producer.subscribe<A where A == A1.E, A1: RxSwift.ObserverType>(A1) -> RxSwift.Disposable Producer.swift:24
      RxSwift   (extension in RxSwift):   RxSwift.ObservableType.subscribe((RxSwift.Event<A.E>) -> ()) -> RxSwift.Disposable ObservableType+Extensions.swift:25
      Hanako    closure #1 (RxSwift.Event<Swift.Int>) -> () in Hanako.ContestChatViewModel.refreshMessages(tableView: __C.UITableView?) -> () ContestChatViewModel.swift:133
      Hanako    reabstraction thunk helper from @escaping @callee_guaranteed (@guaranteed RxSwift.Event<Swift.Int>) -> () to @escaping @callee_guaranteed (@in_guaranteed RxSwift.Event<Swift.Int>) -> () <compiler-generated>:0
      RxSwift   partial apply forwarder for closure #1 (RxSwift.Event<A.E>) -> () in (extension in RxSwift):RxSwift.ObservableType.subscribe((RxSwift.Event<A.E>) -> ()) -> RxSwift.Disposable ObservableType+Extensions.swift:23
      RxSwift   RxSwift.AnonymousObserver.onCore(RxSwift.Event<A>) -> () AnonymousObserver.swift:24
      RxSwift   RxSwift.ObserverBase.on(RxSwift.Event<A>) -> () ObserverBase.swift:18
      RxSwift   protocol witness for RxSwift.ObserverType.on(RxSwift.Event<A.E>) -> () in conformance RxSwift.ObserverBase<A> : RxSwift.ObserverType in RxSwift <compiler-generated>:0
      RxSwift   RxSwift.Sink.forwardOn(RxSwift.Event<A.E>) -> () Sink.swift:34
      RxSwift   closure #1 (A.E) -> A.E in RxSwift.(TimerSink in _92B4E76F25CED73665C45EB7986E9847).run() -> RxSwift.Disposable Timer.swift:66
      RxSwift   closure #2 () -> () in RxSwift.DispatchQueueConfiguration.schedulePeriodic<A>(_: A, startAfter: Swift.Double, period: Swift.Double, action: (A) -> A) -> RxSwift.Disposable DispatchQueueConfiguration.swift:98
      RxSwift   reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @escaping @callee_unowned @convention(block) () -> () <compiler-generated>:0
      
      

      The crash also happens in the very same location but is triggered from another function in our Code. Stack Trace during crash is just the same (above calling this function).

      static func getDate(_ key: String, defValue: Date = Date()) -> Date {
        guard
      	let realm = try? Realm.tryCreate(),
              // next line will also crash on very rare occasions
      	let item = realm.object(ofType: CacheDateValue.self, forPrimaryKey: key) else {
      		return defValue
      	}
      	return item.value
      }
      

      These functions have in common: they are called from a timer (see second last line in the stack trace):

              let timer = DispatchSource.makeTimerSource(queue: self.queue)
              timer.schedule(deadline: initial, repeating: dispatchInterval(period), leeway: self.leeway)
              timer.setEventHandler(handler: {
                  if cancelTimer.isDisposed {
                      return
                  }
                  timerState = action(timerState)
              })
      

      Versions used:

      Installing Realm (3.21.0)
      Installing RealmSwift (3.21.0)
      Installing RxRealm (0.7.6)
      Installing RxSwift (4.5.0)
      

            Assignee:
            thomas.goyne@mongodb.com Thomas Goyne
            Reporter:
            unitosyncbot Unito Sync Bot
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: