realm-swift: Crash - Operation not permitted
We experience a extrem frequent crash since we upgraded to Realm 2.0.2. I believe this has to do something (again) with FileProtection / Background execution.
I’m not able to reproduce this locally but this affects a lot app sessions. We do have a large userbase and it seems that it affects around 15% of our users but crashes very frequently for this users.
What’s strange about this - Fabric shows 100% App In-Focus for this crash - so maybe this is during a transition from/to the background? As this crashes before we do anything in the app it’s hard to say.
Goals
We try to open the database at the very beginning of our app. We supported multiple background modes, i think this might be something with BackgroundFetch or background BT-Communication.
With 1.x everything worked as expected.
Expected Results
No crash 😉
Actual Results
What we see on Fabric: (shortened the path)
fatal error: 'try!' expression unexpectedly raised an error:
Error Domain=io.realm Code=2 "Unable to open a realm at path 'path/db..realm.lock': open() failed: Operation not permitted."
UserInfo={
Error Code=2, NSFilePath=path/db.realm.lock,
Underlying=open("path/db.realm.lock") failed: Operation not permitted,
NSLocalizedDescription=Unable to open a realm at path '/path/db.realm.lock': open() failed: Operation not permitted.
}:
file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-800.0.46.2/src/swift/stdlib/public/core/ErrorType.swift, line 178
The stack trace is confusing and points to method-calls that can’t be called from that point, so I guess fabric records something wrong.
Crashed: db.queue
0 libswiftCore.dylib 0x10201a848 _TFs16_assertionFailedFTVs12StaticStringSSS_Su5flagsVs6UInt32_Os5Never + 164
1 libswiftCore.dylib 0x10203ac00 swift_unexpectedError_merged + 484
2 libswiftCore.dylib 0x10203aa00 swift_unexpectedError + 26
// 3 - Fabric fail? - I think this points to let _ = try! Realm(configuration: config)
3 OurApp 0x1007ba340 static Database.(reset() -> ()).(closure #1).(closure #1) (Database.swift)
4 libdispatch.dylib 0x1804fd1c0 _dispatch_client_callout + 16
5 libdispatch.dylib 0x18050a860 _dispatch_barrier_sync_f_invoke + 84
6 OurApp 0x1007ba030 Database.init(databaseVersion : Int) -> Database (Database.swift)
7 OurApp 0x1008035d0 init(databaseVersion : Int, environment : Environment) (Database.swift:63)
8 OurApp 0x100803f18 static setup(Int, environment : Environment) -> () (AppDelegate.swift)
9 OurApp 0x100148000 specialized AppDelegate.application(UIApplication, didFinishLaunchingWithOptions : [UIApplicationLaunchOptionsKey : Any]?) -> Bool (AppDelegate.swift)
10 OurApp 0x10013ebcc @objc AppDelegate.application(UIApplication, didFinishLaunchingWithOptions : [UIApplicationLaunchOptionsKey : Any]?) -> Bool (AppDelegate.swift)
11 UIKit 0x18752f42c -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 400
12 UIKit 0x18773fb70 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 3524
13 UIKit 0x1877458e0 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1656
14 UIKit 0x18775a080 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke.3134 + 48
15 UIKit 0x1877428c4 -[UIApplication workspaceDidEndTransaction:] + 168
16 FrontBoardServices 0x1832158bc __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 36
17 FrontBoardServices 0x183215728 -[FBSSerialQueue _performNext] + 176
18 FrontBoardServices 0x183215ad0 -[FBSSerialQueue _performNextFromRunLoopSource] + 56
19 CoreFoundation 0x181622278 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
20 CoreFoundation 0x181621bc0 __CFRunLoopDoSources0 + 524
21 CoreFoundation 0x18161f7c0 __CFRunLoopRun + 804
22 CoreFoundation 0x18154e048 CFRunLoopRunSpecific + 444
23 UIKit 0x1875285dc -[UIApplication _run] + 608
24 UIKit 0x187523360 UIApplicationMain + 208
25 OurApp 0x100143aac main (AppDelegate.swift:30)
26 libdispatch.dylib 0x1805305b8 (Missing)
Steps to Reproduce
We are not able to reproduce this with an attached xcode, nor we know how to trigger this.
Code Sample
At this state nothing more than the following happend:
let config = Realm.Configuration(
// Path
fileURL: dbPath,
// Set the new schema version. This must be greater than the previously used
// version (if you've never set a schema version before, the version is 0).
schemaVersion: UInt64(databaseVersion)
)
let _ = try! Realm(configuration: config)
// As stated in the docs.
try! FileManager.default.setAttributes([FileAttributeKey.protectionKey : FileProtectionType.none], ofItemAtPath: realmDirectory.path)
What we tried so far
We did two emergency releases hoping we could find a workaround for this but the crash still occurs.
Emergency release 1: We set the file protection level of all Realm related files to FileProtectionType.none as first thing after app launch. - Still crashes
Emergency release 2: Also we do this on applicationWillResignActive and applicationDidBecomeActive. - Still crashes
func fixRealmFileProtection(withBase baseDir: URL? = nil) {
var docsDir: URL?
if baseDir.isNil {
docsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
docsDir?.appendPathComponent("realm")
}
else {
docsDir = baseDir
}
if let docsDir = docsDir {
try? FileManager.default.contentsOfDirectory(atPath: docsDir.path).forEach({ (file) in
var fileDir = docsDir
fileDir.appendPathComponent(file)
var isDir: ObjCBool = false
if FileManager.default.fileExists(atPath: fileDir.path, isDirectory: &isDir) {
try? FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.none], ofItemAtPath: fileDir.path)
if isDir.boolValue {
fixRealmFileProtection(withBase: fileDir)
}
}
})
}
}
Version of Realm and Tooling
Realm version: 2.0.2
Xcode version: 8
iOS/OSX version: 9.3.5 - 1.1.0
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 3
- Comments: 21 (9 by maintainers)
We are currently rolling out a version with realm 2.1.1. Will report here if anything changes.