realm-swift icon indicating copy to clipboard operation
realm-swift copied to clipboard

EXC_BAD_ACCESS on RLMSwiftBridgeValue when adding objects

Open eliyap opened this issue 2 years ago • 3 comments

How frequently does the bug occur?

Sometimes

Description

When adding an object to a local realm, the app sometimes (about 1/3 chance) crashes with EXC_BAD_ACCESS.

Stacktrace & log output

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=257, address=0xa)
    frame #0: 0x000000000000000a
  * frame #1: 0x000000010351dc0c RedSkyUI`RLMBridgeSwiftValue(value=0x000000028340a910) at RLMUtil.mm:96:12
    frame #2: 0x000000010322b728 RedSkyUI`RLMAccessorContext::propertyValue(this=0x000000016ce67b20, obj=0x000000028340a910, propIndex=0, prop=0x0000000282dd2220) at RLMAccessor.mm:862:11
    frame #3: 0x000000010322fabc RedSkyUI`RLMAccessorContext::value_for_property(this=0x000000016ce67b20, obj=0x000000028340a910, (null)=0x00000002828efe00, propIndex=0) at RLMAccessor.mm:1161:16
    frame #4: 0x000000010322f2b0 RedSkyUI`realm::Object realm::Object::create<objc_object* __strong, RLMAccessorContext>(ctx=0x000000016ce67b20, realm=std::__1::shared_ptr<realm::Realm>::element_type @ 0x0000000107c18df8 strong=5 weak=4, object_schema=0x0000000107c22360, value=0x000000028340a910, policy=(create = true, copy = false, update = false, diff = false), current_obj=(value = -1), out_row=0x000000028340a918) at object_accessor.hpp:345:22
    frame #5: 0x000000010322e2ec RedSkyUI`RLMAccessorContext::createObject(this=0x000000016ce67b20, value=0x000000028340a910, policy=(create = true, copy = false, update = false, diff = false), forceCreate=false, existingKey=(value = -1)) at RLMAccessor.mm:1102:9
    frame #6: 0x00000001033272a8 RedSkyUI`RLMAddObjectToRealm(object=0x000000028340a910, realm=0x00000002831c4b00, updatePolicy=RLMUpdatePolicyError) at RLMObjectStore.mm:119:7
    frame #7: 0x00000001035f0390 RedSkyUI`Realm.add(object=0x000000028340a910, update=error, self=RealmSwift.Realm @ 0x000000016ce67d38) at Realm.swift:540:9
    frame #8: 0x000000010309dc64 RedSkyUI`Realm.add(token=RealmSwift.Realm.TransactionToken @ scalar, object=0x000000028340a910, update=error, self=RealmSwift.Realm @ 0x000000016ce67d78) at Realm.TransactionToken.swift:35:9
    frame #9: 0x000000010305f95c RedSkyUI`closure #1 in storeNew(token=RealmSwift.Realm.TransactionToken @ scalar, realm=RealmSwift.Realm @ 0x000000016ce67db8, object=0x000000028340a910) at NewVisitView.swift:84:19
    frame #10: 0x000000010305f988 RedSkyUI`partial apply for closure #1 in storeNew(visit:) at <compiler-generated>:0
    frame #11: 0x000000010309dbc0 RedSkyUI`closure #1 in Realm.writeWithToken<Result>(block=0x10305f96c) at Realm.TransactionToken.swift:28:17
    frame #12: 0x000000010309dc24 RedSkyUI`partial apply for closure #1 in Realm.writeWithToken<A>(withoutNotifying:_:) at <compiler-generated>:0
    frame #13: 0x00000001035ef034 RedSkyUI`Realm.write<Result>(tokens=0 values, block=0x10309dbfc, self=RealmSwift.Realm @ 0x000000016ce67f80) at Realm.swift:258:23
    frame #14: 0x000000010309db38 RedSkyUI`Realm.writeWithToken<Result>(tokens=0 values, block=0x10305f96c, self=RealmSwift.Realm @ 0x000000016ce68008) at Realm.TransactionToken.swift:26:13
    frame #15: 0x000000010305f0c8 RedSkyUI`storeNew(visit=RedSkyUI.VisitModel @ 0x000000016ce68450) at NewVisitView.swift:83:19
    frame #16: 0x000000010305e67c RedSkyUI`NewVisitSheet.addNewVisit(self=RedSkyUI.NewVisitSheet @ 0x000000012db36710) at NewVisitView.swift:62:22
    frame #17: 0x000000010305e46c RedSkyUI`implicit closure #2 in implicit closure #1 in closure #3 in NewVisitSheet.body.getter(self=RedSkyUI.NewVisitSheet @ 0x000000012db36710) at NewVisitView.swift:48:123
    frame #18: 0x0000000102fecca8 RedSkyUI`closure #2 in DoneButton.body.getter(self=(text = "Add Visit", cornerRadius = 12, isEnabled = true, action = 0x0000000103066868)) at DoneShape.swift:30:21
    frame #19: 0x0000000195f8efb0 SwiftUI`___lldb_unnamed_symbol104204 + 28
    frame #20: 0x00000001967b44d0 SwiftUI`___lldb_unnamed_symbol167806 + 52
    frame #21: 0x00000001959bf190 SwiftUI`___lldb_unnamed_symbol63252 + 28
    frame #22: 0x000000019590dde0 SwiftUI`___lldb_unnamed_symbol59563 + 28
    frame #23: 0x00000001959bf190 SwiftUI`___lldb_unnamed_symbol63252 + 28
    frame #24: 0x0000000196259a7c SwiftUI`___lldb_unnamed_symbol127435 + 572
    frame #25: 0x00000001958ea914 SwiftUI`___lldb_unnamed_symbol58986 + 116
    frame #26: 0x00000001958e64d8 SwiftUI`___lldb_unnamed_symbol58926 + 220
    frame #27: 0x00000001958f0c40 SwiftUI`___lldb_unnamed_symbol59054 + 3328
    frame #28: 0x00000001958e9ba4 SwiftUI`___lldb_unnamed_symbol58964 + 116
    frame #29: 0x00000001958ec5a0 SwiftUI`___lldb_unnamed_symbol59010 + 156
    frame #30: 0x00000001941cc928 UIKitCore`-[UIGestureRecognizer _componentsEnded:withEvent:] + 208
    frame #31: 0x00000001941c9500 UIKitCore`-[UITouchesEvent _sendEventToGestureRecognizer:] + 464
    frame #32: 0x0000000194ac7404 UIKitCore`-[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:] + 172
    frame #33: 0x000000019420ac6c UIKitCore`-[UIGestureEnvironment _updateForEvent:window:] + 188
    frame #34: 0x000000019420f5c8 UIKitCore`-[UIWindow sendEvent:] + 3268
    frame #35: 0x000000019420e898 UIKitCore`-[UIApplication sendEvent:] + 672
    frame #36: 0x000000019420df54 UIKitCore`__dispatchPreprocessedEventFromEventQueue + 7088
    frame #37: 0x0000000194255cac UIKitCore`__processEventQueue + 5632
    frame #38: 0x000000019455e360 UIKitCore`__eventFetcherSourceCallback + 224
    frame #39: 0x000000019205a22c CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
    frame #40: 0x0000000192066614 CoreFoundation`__CFRunLoopDoSource0 + 176
    frame #41: 0x0000000191fea51c CoreFoundation`__CFRunLoopDoSources0 + 244
    frame #42: 0x0000000191fffeb8 CoreFoundation`__CFRunLoopRun + 836
    frame #43: 0x00000001920051e4 CoreFoundation`CFRunLoopRunSpecific + 612
    frame #44: 0x00000001cac73368 GraphicsServices`GSEventRunModal + 164
    frame #45: 0x00000001944b5c98 UIKitCore`-[UIApplication _run] + 888
    frame #46: 0x00000001944b58fc UIKitCore`UIApplicationMain + 340
    frame #47: 0x000000019a92a2a0 libswiftUIKit.dylib`UIKit.UIApplicationMain(Swift.Int32, Swift.Optional<Swift.UnsafeMutablePointer<Swift.UnsafeMutablePointer<Swift.Int8>>>, Swift.Optional<Swift.String>, Swift.Optional<Swift.String>) -> Swift.Int32 + 104
    frame #48: 0x00000001030d1494 RedSkyUI`static UIApplicationDelegate.main() at <compiler-generated>:0
    frame #49: 0x00000001030d141c RedSkyUI`static AppDelegate.$main(self=RedSkyUI.AppDelegate) at AppDelegate.swift:10:1
    frame #50: 0x00000001030d1518 RedSkyUI`main at <compiler-generated>:0
    frame #51: 0x00000001b0245948 dyld`start + 2504

Can you reproduce the bug?

Yes, sometimes

Reproduction Steps

I am creating a test object

internal final class RealmTestObject: RealmSwift.Object {
    @Persisted
    public var name: String
    
    init(name: String) {
        super.init()
        self.name = name
    }
    
    override required init() {
        super.init()
    }
}

and adding it with a convenience function

Realm wrapper functions
public extension Realm {
    /** A token structure, the existence of which guarantees we are in a `Realm` `write` transaction.
        Require this struct to be passed into methods which are only safe to perform within a `write` transaction.
     */
    struct TransactionToken {
        /// Allow instantiation in the function below and nowhere else.
        /// This encourages programmers not to simply fabricate a token, which would defeat the purpose of this system.
        fileprivate init() {}
    }
    
    @discardableResult
    func writeWithToken<Result>(
        withoutNotifying tokens: [NotificationToken] = [],
        _ block: (TransactionToken) throws -> Result
    ) throws -> Result {
        try write(withoutNotifying: tokens) {
            /// Pass in a token object to demarkate that we are in a write transaction.
            try block(TransactionToken())
        }
    }
}

public extension Realm {
    func add(_ token: TransactionToken, object: Object, update: UpdatePolicy = .error) {
        add(object, update: update)
    }
}
func storeNew(visit: VisitModel) -> Result<Void, RealmError> {
    guard let realm = try? Realm(configuration: .init()) else {
        return .failure(.openRealmFailed)
    }
    
    do {
        let object = RealmTestObject(name: visit.name)
        try realm.writeWithToken { token in
            realm.add(token, object: object, update: .error)
        }
    } catch {
        return .failure(.write(error))
    }
    print("test object succeeded")
    return .success(Void())
}

Version

10.28.6

What SDK flavour are you using?

Local Database only

Are you using encryption?

No, not using encryption

Platform OS and version(s)

Xcode 14, macOS 13, iOS 16, all beta 5

Build environment

Xcode version: Version 14.0 beta 5 (14A5294e) Dependency manager and version: Swift Package Manager

eliyap avatar Aug 20 '22 03:08 eliyap

Same happens when creating a new object with a one-to-many relationship (synced db). It crashes with BAD_ACCESS in

    internal mutating func set(_ object: ObjectBase, value: Value) {
        if value is MutableRealmCollection {
            (get(object) as! MutableRealmCollection).assign(value)
            return
        }
        switch storage {
        case let .unmanagedObserved(_, key):
            let name = RLMObjectBaseObjectSchema(object)!.properties[Int(key)].name
            object.willChangeValue(forKey: name)       <----- HERE
            storage = .unmanagedObserved(value: value, key: key)
            object.didChangeValue(forKey: name)
        case .managed(let key), .managedCached(_, let key):
            Value._rlmSetProperty(object, key, value)
        case .unmanaged, .unmanagedNoDefault:
            storage = .unmanaged(value: value, indexed: false, primary: false)
        }
    }

Same code compiled with XCode 13 (any versions) works flawlessly.

Nerkyator avatar Aug 22 '22 11:08 Nerkyator

Hi @eliyap thanks for the code sample, we will try reproduce the issue. @Nerkyator would you be able to open a new issue describing your crash? Thanks.

leemaguire avatar Aug 24 '22 15:08 leemaguire

@Nerkyator would you be able to open a new issue describing your crash? Thanks.

Sure, here it is!

Nerkyator avatar Aug 24 '22 15:08 Nerkyator