Realm-cocoa: Infinite Recursion Crash on App Backgrounding

Created on 16 Mar 2016  路  11Comments  路  Source: realm/realm-cocoa

Goals

Background the application.

Expected Results

Application enters the background without crashing.

Actual Results

Realm occasionally gets into an infinite recursion and crashes after background the application.

Thread : Crashed: com.apple.main-thread
0   Remind101                      0x1004a8b4c long long realm::Array::get<4ul>(unsigned long) const + 8
1   Remind101                      0x10057c5c8 realm::Spec::get_public_column_type(unsigned long) const + 8260
2   Remind101                      0x10057c5c8 realm::Spec::get_public_column_type(unsigned long) const + 8260
3   Remind101                      0x10057c5c8 realm::Spec::get_public_column_type(unsigned long) const + 8260
4   Remind101                      0x10057c5c8 realm::Spec::get_public_column_type(unsigned long) const + 8260
5   Remind101                      0x10057c5c8 realm::Spec::get_public_column_type(unsigned long) const + 8260

A full crash report can be found here: http://crashes.to/s/addba1ee27b

Steps to Reproduce

Nothing solid. We have over 4,000 crash reports from Fabric of this scenario in our application, but the only pattern we can find is that it always happens when the application is backgrounded.

Code Sample

The code we have in didEnterBackground: does 4 things:

  • Persists NSUserDefaults via synchronize
  • Saves our Core Data context (we're mid-migration)
  • Creates an event tracking payload and uses a background task to dispatch our gathered tracking data to our server
  • Leaves a breadcrumb for our crash reporter.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [[NSUserDefaults standardUserDefaults] synchronize];
    [[RDObjectManager sharedManager] saveContext]; // Core Data save

    __block UIBackgroundTaskIdentifier bgTask;
    void (^completion)() = ^void() {
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    };

    [RDEvents fireEvent:@"app_closed"]; // Adds event payload to an in-memory dictionary

    bgTask = [application beginBackgroundTaskWithExpirationHandler:completion];
    [RDEvents flushEvents:completion]; // Posts our event tracking data to server and calls completion block to end task

    Breadcrumb(); // Logs this method name for our crash logs
}

From our logs it looks like using that background task keeps our network connections alive for a period of time while that events request completes, including our Pusher sockets. I think if we receive additional data from either Pusher or other pending network requests, that's probably triggering a write transaction or something else in the Realm library that doesn't like being in the background.

Version of Realm and Tooling

ProductName:    Mac OS X
ProductVersion: 10.10.5
BuildVersion:   14F1605

/Applications/Xcode.app/Contents/Developer
Xcode 7.2.1
Build version 7C1002

/Users/alexleffelman/.rbenv/shims/pod
0.39.0.beta.5
Realm (0.96.2)

/bin/bash
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin14)

/usr/local/bin/carthage
0.6.3
(not in use here)

/usr/bin/git
git version 2.5.4 (Apple Git-61)

I know that's a very old version of Realm, and we've updated for our next release, but I wanted to raise this issue 1) in case it's something you recognize as fixed in a more recent version, and 2) to bring it to your attention if looks like a problem on your end.

O-Community Pipeline-On-Hold Reproduction-Required T-Bug-Crash

All 11 comments

Thanks for filing this @LeffelMania. What are the NSFileProtection attributes of the Realm files and their parent directory? By default on iOS 8 and later, files have NSFileProtectionComplete attributes, which prevents them from being accessed while the device is locked. If you intend to access Realm files while the device is locked, you'll need to allow access to them by setting a more relaxed protection setting, as described in the Using Realm with Background App Refresh section of our docs.

We didn't do anything with the file protection settings for our Realm configuration, so I'm sure that's at least part of the problem. Is it your opinion that this stack trace is a symptom of that? From the documentation it sounds like an exception should be thrown if we don't have the necessary permissions, which doesn't seem to be the case here.

I'm not sure.

Small update: We adjusted our file permissions as discussed above and are experiencing the crash still.

I'm sorry to hear that! If you could share a sample Xcode project that demonstrates this in practice, that would help us investigate.

Also seeing similar stack trace in a crash report (Realm 0.100.0). Not sure if this happens when user is closing the app or not.

http://crashes.to/s/ff229888691

Sorry to hear that you were still experiencing issues with that. Since then we've released few further versions and made significant changes in general. Can any of you confirm that this still occurs with the latest version?

As seen in #3659, we plan to improve our error reporting around NSFileProtection, so that we might be able to prevent such failures in the future. But we have yet to determine whether that really originate from that. So if you should be able to reproduce the problem yourself and could describe us how and share a built version of your app (.ipa) with us privately to [email protected], that could help us already a lot.

Does anyone have any updates with this issue in latest Realm version (1.0.1)?

We are also experiencing the issue with Realm 1.0.1. Any updates?

We'd love to see a sample project and steps that allow us to reproduce this issue. We can't make much progress on this until then.

@jpsim, I will try to reproduce it on my side and create a sample project with the issue.

Was this page helpful?
0 / 5 - 0 ratings