realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.27k stars 2.14k forks source link

Crash on RLMSchema sharedShema Xcode 15, Below iOS 17 when using with SwiftData #8397

Open yasheedv opened 11 months ago

yasheedv commented 11 months ago

How frequently does the bug occur?

Always

Description

A App is crashing when running below iOS 17 with the project having SwiftData model The crash is happening inside RLMSchema sharedShema unsigned int numClasses; using malloc_ptr = std::unique_ptr<__unsafe_unretained Class[], decltype(&free)>; malloc_ptr classes(objc_copyClassList(&numClasses), &free);

Tried adding the -Wl,-ld_classic options to the OTHER_LDFLAGS build in the project settings. But same crash is happening.

Stacktrace & log output

No response

Can you reproduce the bug?

Always

Reproduction Steps

  1. Create a new project.
  2. Set Minimum deployment target to iOS 13
  3. Create a SwiftData Model using @available(iOS 17, *) check
  4. Install Realm using SPM
  5. Create a Realm Model
  6. Access the default Realm in AppDelegate didFinishLaunchingWithOptions
  7. Run the application on a device that is below iOS 17
  8. Then the application will crash

Project URL: SwiftDataRealm.zip

Version

v10.43.1

What Atlas Services are you using?

Local Database only

Are you using encryption?

No

Platform OS and version(s)

iOS 16.6.1

Build environment

Xcode version: Xcode 15 Dependency manager and version: SPM

yasheedv commented 11 months ago

The crash is happening if I add a SwiftData model inside the project.

liujieyuu commented 6 months ago

@yasheedv Has this problem been solved? I also encountered this problem

showchi commented 6 months ago

10.48.0 still crashes; RealmWithConfiguration:error: is called when starting.

Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

Crash Below iOS17, Xcode 15.2

+ (instancetype)sharedSchema {
    @synchronized(s_localNameToClass) {
        // We replace this method with one which just returns s_sharedSchema
        // once initialization is complete, but we still need to check if it's
        // already complete because it may have been done by another thread
        // while we were waiting for the lock
        if (s_sharedSchemaState == SharedSchemaState::Initialized) {
            return s_sharedSchema;
        }

        if (s_sharedSchemaState == SharedSchemaState::Initializing) {
            @throw RLMException(@"Illegal recursive call of +[%@ %@]. Note: Properties of Swift `Object` classes must not be prepopulated with queried results from a Realm.", self, NSStringFromSelector(_cmd));
        }

        s_sharedSchemaState = SharedSchemaState::Initializing;
        try {
            // Make sure we've discovered all classes
            {
                unsigned int numClasses;
                using malloc_ptr = std::unique_ptr<__unsafe_unretained Class[], decltype(&free)>;
                malloc_ptr classes(objc_copyClassList(&numClasses), &free); # Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
                RLMRegisterClassLocalNames(classes.get(), numClasses);
            }

            [s_localNameToClass enumerateKeysAndObjectsUsingBlock:^(NSString *, Class cls, BOOL *) {
                registerClass(cls);
            }];
        }
        catch (...) {
            s_sharedSchemaState = SharedSchemaState::Uninitialized;
            throw;
        }

        // Replace this method with one that doesn't need to acquire a lock
        Class metaClass = objc_getMetaClass(class_getName(self));
        IMP imp = imp_implementationWithBlock(^{ return s_sharedSchema; });
        class_replaceMethod(metaClass, @selector(sharedSchema), imp, "@@:");

        s_sharedSchemaState = SharedSchemaState::Initialized;
    }

    return s_sharedSchema;
}
lizp-peng commented 6 months ago

请问如何解决,有人知道吗

jln19 commented 5 months ago

Same problem for me. Fatal for our app. Is there a workaround?

jln19 commented 5 months ago

Still crashing as of 10.49.1. We wrote a whole new feature for our app using SwiftData and can't release it because Realm crashes on all devices running iOS16 or below.

Line 300 Pods/Realm/Realm/RLMSchema.mm:300 malloc_ptr classes(objc_copyClassList(&numClasses), &free);

tgoyne commented 5 months ago

You can avoid the call to objc_copyClassList() by explicitly setting objectTypes on your Realm configuration.

jln19 commented 5 months ago

You can avoid the call to objc_copyClassList() by explicitly setting objectTypes on your Realm configuration.

@tgoyne Thank you much for this. I'm able to avoid the crash by setting those types.

TomasWell commented 2 months ago

You can avoid the call to objc_copyClassList() by explicitly setting objectTypes on your Realm configuration.

对我有效

rvenable commented 4 weeks ago

Is this related to this known issue in objc_getClassList when there are objects that don't exist on lower platform versions? https://github.com/swiftlang/swift/issues/61215

lkuraer commented 3 weeks ago

I had the same issue. Realm crashed on devices below ios 17, when I have added SwiftData to the project. @tgoyne is right, his comment helped me to solve this. For those who is wondering what he means

let objectTypes: [Object.Type] = [DownloadObject.self, AnotherModel.self, YetAnotherModel.self]

let config = Realm.Configuration( schemaVersion: 10, migrationBlock: { migration, oldSchemaVersion in // Migration logic }, objectTypes: objectTypes )

Realm.Configuration.defaultConfiguration = config

just define realm Object types and list them into the config. And everything will work again.