State Restoration and Background App Refresh Crash

Originator:calebmdavenport
Number:rdar://20841536 Date Originated:May 6 2015
Status:Open Resolved:
Product:iOS Product Version:7.1 - 8.x
Classification:Crash/Hang/Data Loss Reproducible:Always
 
Summary:
I added state restoration to an app in the last update. I imediately started getting an incredibly high number of crash reports from all over the application. Each one crashed in a different thread, in different parts of the app.
 
Every report has two things in common. All of them are SIGSEGV errors with a SEGV_ACCERR error code. All of them reference the following calls in the main thread:

15  libsystem_c.dylib                    0x30b04eb9 exit + 10
16  UIKit                                0x257795e7 -[UIApplication _terminateWithStatus:] + 404
17  UIKit                                0x25964a83 -[UIApplication _updateSnapshotAndStateRestorationArchiveForBackgroundEvent:saveState:exitIfCouldNotRestoreState:] + 108

I did some digging and found that UIKit state restoration fails if the application is launched in the background to perform a background app refresh. The following messages are printed:

Error reading archived restorable state: Error Domain=NSCocoaErrorDomain Code=257 "The operation couldn’t be completed. (Cocoa error 257.)" UserInfo=0x174861dc0 {NSFilePath=/var/mobile/Containers/Data/Application/2AEAAA47-401A-4AD9-ACD4-157EB07E6A9F/Library/Saved Application State/com.north.watchville.savedState/data.data, NSUnderlyingError=0x17425ad90 "The operation couldn’t be completed. Operation not permitted"}

Application could not restore state when launched in background while locked, skipping snapshot/state save when asked to update snapshot in background, and terminating app instead
 
It seems as though the state restoration files are protected in a way that the rest of my application's data is not. The call to exit causes trouble on any background threads that are still running so I see lots of crash reports.
 
Interestingly enough, -[UIApplicationDelegate application:shouldSaveApplicationState:] and -[UIApplication application:shouldRestoreApplicationState:] are never called in this mode. So I never have an option to opt out of state restoration in the background and prevent this crash.

Additionally, while building the sample project for this report, I discovered that if I don't implement

func application(application: UIApplication, willFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
    return true
}

the errors and crashes go away and state restoration works in the background as expected. If it is implemented, state restoration fails with the issues outlined above.

Steps to Reproduce:
In the attached sample application:

- Run the "Foreground" scheme on a device
- Close the application by pressing the home button so that UIKit has a chance to archive all application state
- Sop the application from Xcode
- Run the "Background" scheme on a device while the device is locked

If application:willFinishLaunchingWithOptions: (AppDelegate.swift line 25) is included in the build, you will see errors around state restoration. If it is not included, everything (including state restoration) works as expected.

Expected Results:
State restoration should work, or UIKit should not attempt to archive or restore state in cases where it could fail (background running on a locked device).

Actual Results:
State restoration fails which results in the application terminating itself, resulting in high crash volume.

It prints the following error messages:

Error reading archived restorable state: Error Domain=NSCocoaErrorDomain Code=257 "The operation couldn’t be completed. (Cocoa error 257.)" UserInfo=0x174861dc0 {NSFilePath=/var/mobile/Containers/Data/Application/2AEAAA47-401A-4AD9-ACD4-157EB07E6A9F/Library/Saved Application State/com.north.watchville.savedState/data.data, NSUnderlyingError=0x17425ad90 "The operation couldn’t be completed. Operation not permitted"}

Application could not restore state when launched in background while locked, skipping snapshot/state save when asked to update snapshot in background, and terminating app instead

Then UIApplication terminates itself.

Sample project: http://cl.ly/asp8

Comments

drodriguez

Duplicated in rdar://29094269

By drodrigueztroitino at Nov. 3, 2016, 6:52 p.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!