iOS app crashes with EXC_BREAKPOINT (SIGTRAP) in AppDelegate.applicationWillResignActive - ios

I have an app with very strange crashes that I have been unable to reproduce. I see these crashes in Xcode Organizer and in AppStore connect but not in crash tools (I tried Sentry and Bugsnag).
As far as I understand crash logs, crash occurs in applicationWillResignActive.
Incident Identifier: A15332F7-C7E6-4618-9FEF-7A2E6AD013FF
Hardware Model: iPhone14,5
Process: MyApp [1533]
Path: /private/var/containers/Bundle/Application/408766C6-5645-4592-9D89-CB8DE5D71A76/MyApp.app/MyApp
Identifier: com.myapp.identifier
Version: 1.2.3 (123)
AppStoreTools: 13A1030d
AppVariant: 1:iPhone14,5:15
Code Type: ARM-64 (Native)
Role: Non UI
Parent Process: launchd [1]
Coalition: com.myapp.identifier [899]
Date/Time: 2021-11-12 08:04:45.3781 +0300
Launch Time: 2021-11-12 01:20:00.0202 +0300
OS Version: iPhone OS 15.0 (19A346)
Release Type: User
Baseband Version: 1.00.03
Report Version: 104
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x0000000100602734
Exception Note: EXC_CORPSE_NOTIFY
Terminating Process: exc handler [1533]
Triggered by Thread: 0
Thread 0 name:
Thread 0 Crashed:
0 MyApp 0x0000000100602734 specialized AppDelegate.applicationWillResignActive(_:) + 168
1 MyApp 0x00000001005ff40c AppDelegate.applicationWillTerminate(_:) + 12 (<compiler-generated>:0)
2 MyApp 0x00000001005ff40c #objc AppDelegate.applicationWillTerminate(_:) + 56
3 UIKitCore 0x0000000186a34ddc -[UIApplication _terminateWithStatus:] + 244 (UIApplication.m:6876)
4 UIKitCore 0x0000000186122854 -[_UISceneLifecycleMultiplexer _evalTransitionToSettings:fromSettings:forceExit:withTransitionStore:] + 128 (_UISceneLifecycleMultiplexer.m:808)
5 UIKitCore 0x00000001863172e4 -[_UISceneLifecycleMultiplexer forceExitWithTransitionContext:scene:] + 224 (_UISceneLifecycleMultiplexer.m:482)
6 UIKitCore 0x0000000186a31a5c -[UIApplication workspaceShouldExit:withTransitionContext:] + 212 (UIApplication.m:3792)
7 FrontBoardServices 0x0000000195150c48 __63-[FBSWorkspaceScenesClient willTerminateWithTransitionContext:]_block_invoke_2 + 80 (FBSWorkspaceScenesClient.m:331)
8 FrontBoardServices 0x000000019510b6c4 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 240 (FBSWorkspace.m:352)
9 FrontBoardServices 0x0000000195150be0 __63-[FBSWorkspaceScenesClient willTerminateWithTransitionContext:]_block_invoke + 132 (FBSWorkspaceScenesClient.m:328)
10 libdispatch.dylib 0x0000000183346950 _dispatch_client_callout + 20 (object.m:560)
11 libdispatch.dylib 0x000000018334a3e8 _dispatch_block_invoke_direct + 264 (queue.c:489)
12 FrontBoardServices 0x000000019510cfa4 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 48 (FBSSerialQueue.m:157)
13 FrontBoardServices 0x000000019510c3e4 -[FBSSerialQueue _targetQueue_performNextIfPossible] + 220 (FBSSerialQueue.m:181)
14 FrontBoardServices 0x00000001951109f4 -[FBSSerialQueue _performNextFromRunLoopSource] + 28 (FBSSerialQueue.m:194)
15 CoreFoundation 0x00000001836f6030 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (CFRunLoop.c:1972)
16 CoreFoundation 0x0000000183706cf0 __CFRunLoopDoSource0 + 208 (CFRunLoop.c:2016)
17 CoreFoundation 0x0000000183640ff8 __CFRunLoopDoSources0 + 268 (CFRunLoop.c:2053)
18 CoreFoundation 0x0000000183646804 __CFRunLoopRun + 820 (CFRunLoop.c:2951)
19 CoreFoundation 0x000000018365a3c8 CFRunLoopRunSpecific + 600 (CFRunLoop.c:3268)
20 GraphicsServices 0x000000019ee6b38c GSEventRunModal + 164 (GSEvent.c:2200)
21 UIKitCore 0x00000001860000bc -[UIApplication _run] + 1100 (UIApplication.m:3457)
22 UIKitCore 0x0000000185d7dbe8 UIApplicationMain + 2124 (UIApplication.m:5013)
23 MyApp 0x00000001004a5b18 main + 68 (AppDelegate.swift:19)
24 dyld 0x000000010092da24 start + 520 (dyldMain.cpp:876)
Inside applicationWillResignActive I am fetching data from my local Realm and update values in UserDefaults.
class AppDelegate: UIResponder, UIApplicationDelegate {
let provider = Provider()
func applicationWillResignActive(_ application: UIApplication) {
if userDefaults.bool(forKey: UserDefaults.Keys.keyWidgetEnabled) {
provider.updateUserDefaults()
}
}
}
class Provider {
let database = try! Realm()
...
func updateUserDefaults() {
let defaults = UserDefaults(suiteName: "com.MyApp.identifier")
let currentDisplayDate = CalculationsHelper.getUTCSubmitDate()
let predicateHistoryDisplayDate = NSPredicate(format: "type=%# AND currentSubmitDate = %#", keyDBFood, currentDisplayDate.absoluteDate as NSDate)
let data = self.database.objects(History.self).filter(predicateHistoryDisplayDate)
mealTypesDB.allFoodTypes.forEach{ (type) in
let key = "widget-" + type.rawValue
let predicate = NSPredicate(format: "meal=%#", type.rawValue)
let kcal: Int = data.filter(predicate).sum(ofProperty: "kcal")
defaults?.set(kcal, forKey: key)
}
//set the date of the next day to update the button
let currentSubmitDate = CalculationsHelper.getLocalSubmitDate()
defaults?.set(currentSubmitDate, forKey: "widget-submitDate")
defaults?.synchronize()
if #available(iOS 14.0, *) {
WidgetCenter.shared.reloadAllTimelines()
}
}
}
I used to do this for every user every time they sent the app to background, but for a week now I've only done it for the small fraction of users who have my widget installed. But number of crashes almost didn't change so I think that this bug is not related with Realm or UserDefaults.
As far as I can tell from AppStore connect, I've always had this bug, but only with the release of iOS 15 has the number of crashes dramatically increased. I'm not really sure how this can be resolved and what exactly has changed in iOS 15 that could provoke such a dramatic increase number of crashes.
I found this thread https://developer.apple.com/forums/thread/106261 and tried renaming all my images in the project so that the file names match the name in Assets, but that didn't work.
Does anyone have any idea what I can do to at least figure out the cause of the crashes?

I contacted Apple TSI and they told me to check that the object inside the applicationWillResignActive and applicationWillTerminate method is nil. And to my surprise at the moment of calling applicationWillTerminate the object is really nil.
But can anyone explain how this is possible? This object is initialised in didFinishLaunchingWithOptions and I never make it equal to nil during the app life cycle. Is it possible that iOS is trying to terminate the application for some reason (not enough memory, for example) and tries to remove all objects from memory one by one, and when applicationWillTerminate is called, object is already removed from memory and therefore it is nil? But at which point it's allowed to nil out a variable of a running class?
UPDATE:
I got a response from the Apple team and I think it's very interesting. They said that didFinishLaunchingWithOptions will ALWAYS be called before other lifecycle delegates for
the "standard" lifecycle like applicationWillResignActive and
applicationDidEnterBackground. However, that's NOT the case with applicationWillTerminate. The
termination process can occur outside the normal lifecycle flow and, at
least in theory, there's not reason it couldn't occur before
didFinishLaunchingWithOptions is actually called.
So if I have an optional variable in AppDelegate that is initialized inside didFinishLaunchingWithOptions, it can still be nil in applicationWillTerminate. This is what causes some users to crash.

Are you calling applicationWillResignActive yourself? It looks like you call it from AppDelegate.applicationWillTerminate. You should never call the UIAppDelegate methods yourself, that is an anti-pattern. I'm not sure that causes the crash though, but you may want to introduce a separate method which you call from both.

The fact that you are using a custom crash reporter (Sentry, Bugsnag, ...) could be an issue. When your app crashes, Apple's crash reporter can get confused and the reported line you get will be completely wrong.
You can find more details provided by an Apple engineer on this Apple dev forum post. He recommends only using Apple's own crash reporter because third-party crash reporters are tied to your app process and can corrupt the stack trace when they try to get it while your app is crashing which results in a wrong report in Xcode.

Related

Unexplained crash: NSInvalidArgumentException, same view controller instance pushed more than once

I'm seeing an unexplained crash on my iOS app built with SwiftUI. It only affects some users, and I can't manage to reproduce locally.
Here is the stack trace:
Fatal Exception: NSInvalidArgumentException
<_TtGC7SwiftUI41StyleContextSplitViewNavigationControllerVS_19SidebarStyleContext_: 0x110859800>
is pushing the same view controller instance(<_TtGC7SwiftUI41StyleContextSplitViewNavigationControllerVS_14NoStyleContext_: 0x11088a400>)
more than once which is not supported and is most likely an error in the application : `com.myapp`
Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x1893a186c __exceptionPreprocess
1 libobjc.A.dylib 0x19e3bcc50 objc_exception_throw
2 UIKitCore 0x18b575514 -[UINavigationController pushViewController:transition:forceImmediate:]
3 UIKitCore 0x18b5751f4 -[UINavigationController pushViewController:animated:]
4 UIKitCore 0x18b6047c8 __45-[UISplitViewControllerPanelImpl showColumn:]_block_invoke
5 UIKitCore 0x18b57eda8 -[UINavigationController _executeSplitViewControllerActions:]
6 UIKitCore 0x18b6045bc -[UISplitViewControllerPanelImpl showColumn:]
7 UIKitCore 0x18b5e4c54 -[UISplitViewController showColumn:]
8 SwiftUI 0x1903784f4 closure #1 in closure #1 in NavigationBridge_PhoneTV.push(_:onto:animated:)
9 SwiftUI 0x19042728c thunk for #escaping #callee_guaranteed () -> ()
10 UIKitCore 0x18c23f544 -[_UIAfterCACommitBlock run]
11 UIKitCore 0x18bd6700c _runAfterCACommitDeferredBlocks
12 UIKitCore 0x18bd559a0 _cleanUpAfterCAFlushAndRunDeferredBlocks
13 UIKitCore 0x18bd89bb4 _afterCACommitHandler
14 CoreFoundation 0x18931c358 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
15 CoreFoundation 0x1893165c4 __CFRunLoopDoObservers
16 CoreFoundation 0x189316b74 __CFRunLoopRun
17 CoreFoundation 0x18931621c CFRunLoopRunSpecific
18 GraphicsServices 0x1a0ee2784 GSEventRunModal
19 UIKitCore 0x18bd56ee8 -[UIApplication _run]
20 UIKitCore 0x18bd5c75c UIApplicationMain
21 MYAPP 0x100dbecc0 main + 7 (PushupsMode.swift:7)
22 libdyld.dylib 0x188fd66b0 start
Looking at PushupsMode.swift:7 it seems completely unrelated:
import Foundation
extension WorkoutModel {
mutating func startPushups() {
var pushupsCount = 10 + p.intensityOptionPicked * 10
if(round > 6 || round < 3) { // <<--- this is the line crashing
pushupsCount = Int(pushupsCount / 2)
}
// More code after that point
}
}
The round variable is defined in another file, but there's nothing really significant around it:
import Foundation
import SwiftUI
struct WorkoutModel: Identifiable {
// bunch of stuff before
var round: Int = -1
// bunch of stuff after
}
Obviously looking at the error message, it seems like something is getting pushed twice... however since I'm using SwiftUI I'm not entirely sure how I could have even done that.
Any pointers would be appreciated!
Your problem may be that you are defining pushupsCount as an Int( on PushupsMode.swift:8 which is causing the exception on :7 from :8 failing pre-execution. Try defining it as pushupsCount = Int pushupsCount / 2 .
Using pushViewController:transition:forceImmediate is not a good idea because pushViewController:animated will be calling on this undocumented method. Rather than changing transition this way you can use other documented methods for changing animation. This thread might be helpful for you. You will also need to add guard in pushViewController:animated and will also need to set transition.duration. Calling pushViewController again and again is perhaps causing crash of app.
This problem is caused when you place your navigationLink inside of a List with observed data.
How to fix :
Remove NavigationLink from inside of the list and place it outside.

JSONDecoder crashing on TestFlight / AppStore

I am working on my Apple Watch app. Most of my components use JSON and use the Swift Codable protocol to decode JSON.
Now I wanted to prepare my release, but I received a message by a Beta tester that the App was always crashing on his Series 3.
After I installed the TestFlight build on my Series 3 I could reproduce the issue.
The crash logs from TestFlight and the crash logs extracted from my iPhone indicate that the crash is happening while the JSON gets decoded.
I have rather complex JSON structures, but I did not do any changes to them since the last update. Furthermore, decoding JSON works fine on Xcode builds (also on Series 3) and on newer Apple Watches (Series 4 + 5). I am struggling to find out what could cause the issue.
I discovered a post in the Apple developer forums with a similar issue, but without a solution to it: https://forums.developer.apple.com/thread/124627
Here's a part of the Stacktrace of my crash log:
Date/Time: 2020-02-05 08:37:42.9924 +0100
Launch Time: 2020-02-05 08:37:40.0000 +0100
OS Version: Watch OS 6.1.2 (17S5792a)
Release Type: User
Baseband Version: 4.40.02
Report Version: 104
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Application Specific Information:
abort() called
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x4d9aefc8 __pthread_kill + 8
1 libsystem_pthread.dylib 0x4da260be pthread_kill + 108
2 libsystem_c.dylib 0x4d9383a4 abort + 84
3 libswiftCore.dylib 0x6cffbade swift_vasprintf+ 2341598 (char**, char const*, char*) + 0
4 libswiftCore.dylib 0x6d00932c swift::TargetMetadata<swift::InProcess>::getGenericArgs+ 2396972 () const + 0
5 libswiftCore.dylib 0x6d00508c _swift_initClassMetadataImpl+ 2379916 (swift::TargetClassMetadata<swift::InProcess>*, swift::ClassLayoutFlags, unsigned long, swift::TypeLayout const* const*, unsigned long*, bool) + 28
6 libswiftCore.dylib 0x6d005c86 swift_initClassMetadata2 + 22
7 libswiftCore.dylib 0x6cfdc6fc type metadata completion function for _KeyedDecodingContainerBox + 50
8 libswiftCore.dylib 0x6d00a6c2 swift::MetadataCacheEntryBase<(anonymous namespace)::GenericCacheEntry, void const*>::doInitialization+ 2401986 (swift::ConcurrencyControl&, swift::MetadataCompletionQueueEntry*, swift::MetadataRequest) + 178
9 libswiftCore.dylib 0x6d003a0c swift_getGenericMetadata + 1124
10 libswiftCore.dylib 0x6cdf4210 KeyedDecodingContainer.init<A>+ 213520 (_:) + 40
11 libswiftFoundation.dylib 0x6d156e0a __JSONDecoder.container<A>+ 323082 (keyedBy:) + 678
12 libswiftFoundation.dylib 0x6d1a3a1c protocol witness for Decoder.container<A>+ 637468 (keyedBy:) in conformance __JSONDecoder + 18
13 libswiftFoundation.dylib 0x6d1592b6 protocol witness for Decoder.container<A>+ 332470 (keyedBy:) in conformance __JSONDecoder + 32
14 libswiftCore.dylib 0x6cfdb1cc dispatch thunk of Decoder.container<A>+ 2208204 (keyedBy:) + 24
15 WatchSonos WatchKit Extension 0x00440bf2 0x358000 + 953330
16 WatchSonos WatchKit Extension 0x0043d08c 0x358000 + 938124
17 libswiftCore.dylib 0x6cfdb156 dispatch thunk of Decodable.init+ 2208086 (from:) + 12
18 libswiftFoundation.dylib 0x6d16fbee __JSONDecoder.unbox_+ 424942 (_:as:) + 4014
19 libswiftFoundation.dylib 0x6d156816 JSONDecoder.decode<A>+ 321558 (_:from:) + 642
20 libswiftFoundation.dylib 0x6d22af98 dispatch thunk of JSONDecoder.decode<A>+ 1191832 (_:from:) + 28
21 WatchSonos WatchKit Extension 0x0045db0c 0x358000 + 1071884
22 WatchSonos WatchKit Extension 0x00461cce 0x358000 + 1088718
23 WatchSonos WatchKit Extension 0x00461bde 0x358000 + 1088478
24 WatchSonos WatchKit Extension 0x00420ffa 0x358000 + 823290
25 WatchSonos WatchKit Extension 0x00425914 0x358000 + 842004
26 libdispatch.dylib 0x4d851846 _dispatch_call_block_and_release + 10
27 libdispatch.dylib 0x4d8528b8 _dispatch_client_callout + 6
28 libdispatch.dylib 0x4d85c6b0 _dispatch_main_queue_callback_4CF + 868
29 CoreFoundation 0x4dcdbbaa __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 10
30 CoreFoundation 0x4dcd7c00 __CFRunLoopRun + 1832
31 CoreFoundation 0x4dcd723a CFRunLoopRunSpecific + 370
32 GraphicsServices 0x50aebcd0 GSEventRunModal + 96
33 UIKitCore 0x65c91580 UIApplicationMain + 1730
34 libxpc.dylib 0x4da73c80 _xpc_objc_main.cold.3 + 152
35 libxpc.dylib 0x4da649b0 _xpc_objc_main + 184
36 libxpc.dylib 0x4da668c4 xpc_main + 110
37 Foundation 0x4e56b0c6 +[NSXPCListener serviceListener] + 0
38 PlugInKit 0x556d726c 0x556c5000 + 74348
39 WatchKit 0x5cfe9afe WKExtensionMain + 62
40 WatchKit 0x5d09f020 main + 10
Here's the position in the code that crashes:
required public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.id = try values.decode(String.self, forKey: .id)
do {
if values.contains(.groups) {
let groups = try values.decode(Dictionary<String, SonosGroup>.self, forKey: .groups)
self.groups = groups
}
if values.contains(.players) {
let players = try values.decode(Array<SonosPlayer>.self, forKey: .players)
self.players = players
}
}catch let error {
print("Error decoding groups \(error)")
}
}
For me this looks like an Apple bug and I filed feedback for it, but this is no solution for the next release.
Does anyone know what's the difference between a TestFlight build and an Xcode release build?
I tried setting a different optimization level, disabling bitcode (not allowed for Apple Watch Apps) and I started replacing Codable with the good old JSONSerialization.
If anyone knows more about it, thank you for that.
Kind regards
Alex
I was having a very similar problem with Encodable and Decodable's in a swift package. Setting DEAD_CODE_STRIPPING = NO in my apps target fixed it. This seems to be a weird leftover of this bug:
https://bugs.swift.org/browse/SR-11564?focusedCommentId=51285&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-51285

Crash when fetching with CoreData

My app is in production and I've been getting a few crashes on Crashlytics when trying to cast the first element of a festRequest to a certain entity. I've not been able to recreate this crash no matter how hard I try.
static func getSettings() -> NotificationSettingsMO {
var settings: NotificationSettingsMO!
let moc = DataController.shared.managedObjectContext
moc.performAndWait {
do {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "NotificationSettings")
settings = try moc.fetch(fetchRequest).first as! NotificationSettingsMO
} catch {
print(error)
}
}
return settings
The crash happens when trying to cast the first element of the request to NotificationSettingsMO and I'm sure the entity exists since I create it when the user is created. This also only happens to a small percentage of users, but since it crashes the app I want to try and figure out what is causing it.
EDIT: I've attached the crash log
Crashed: com.apple.main-thread
0 MyApp 0x100073360 specialized static NotificationSettingsMO.(getSettings() -> NotificationSettingsMO).(closure #1) (NotificationSettingsMO.swift:25)
1 MyApp 0x10007309c partial apply for static NotificationSettingsMO.(getSettings() -> NotificationSettingsMO).(closure #1) (NotificationSettingsMO.swift)
2 CoreData 0x18311d08c developerSubmittedBlockToNSManagedObjectContextPerform + 196
3 CoreData 0x18311cf54 -[NSManagedObjectContext performBlockAndWait:] + 220
4 MyApp 0x100072fa8 specialized static NotificationSettingsMO.getSettings() -> NotificationSettingsMO (NotificationSettingsMO.swift)
5 MyApp 0x1000d6190 AppDelegate.getDataOnLaunch() -> () (AppDelegate.swift)
6 MyApp 0x1000da4bc specialized AppDelegate.application(UIApplication, didFinishLaunchingWithOptions : [UIApplicationLaunchOptionsKey : Any]?) -> Bool (AppDelegate.swift:99)
7 MyApp 0x1000d3eb8 #objc AppDelegate.application(UIApplication, didFinishLaunchingWithOptions : [UIApplicationLaunchOptionsKey : Any]?) -> Bool (AppDelegate.swift)
8 UIKit 0x1863f29c0 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 400
9 UIKit 0x186622184 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2904
10 UIKit 0x1866265f0 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1684
11 UIKit 0x186623764 -[UIApplication workspaceDidEndTransaction:] + 168
12 FrontBoardServices 0x182bbf7ac __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 36
13 FrontBoardServices 0x182bbf618 -[FBSSerialQueue _performNext] + 168
14 FrontBoardServices 0x182bbf9c8 -[FBSSerialQueue _performNextFromRunLoopSource] + 56
15 CoreFoundation 0x1811d509c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
16 CoreFoundation 0x1811d4b30 __CFRunLoopDoSources0 + 540
17 CoreFoundation 0x1811d2830 __CFRunLoopRun + 724
18 CoreFoundation 0x1810fcc50 CFRunLoopRunSpecific + 384
19 UIKit 0x1863eb94c -[UIApplication _run] + 460
20 UIKit 0x1863e6088 UIApplicationMain + 204
21 MyApp 0x10001ee18 main (Measurement+Network.swift:26)
22 libdispatch.dylib 0x180c9a8b8 (Missing)
The object does not exists so it crashes. Personally I HATE force casting in swift. The whole point of optionals is to help you manage when something is nil. Putting as! in your code is asking the program to crash. I would suggest removing it and replacing it with an if let. If you are 100% sure that it will never be nil then you should still use an if let and in the else report to crash service that it happened (use Crashlytics recordError - it will show up along with your crashes).
As for your statement:
I'm sure the entity exists since I create it when the user is created
to put it bluntly - you are wrong. Computers are always right and humans are always wrong.
Here are the possible reasons why:
There was an error saving it to core data I suspect that like most programs when you saved the object to core data you did not check for errors - or if you did you didn't really know what to do with the error. If you were smart you would have logged it. The most common error to get is lack of space on the hard disk. If the object wasn't saved in the first place then it wouldn't be there when you fetch it.
The object was there but was deleted. If you have anywhere in your code that deletes this object, then consider the possibility that it was deleted before this code ran. Look for multithreading and race conditions.
The object wasn't save yet. If you have ANY multithreading in the app you should consider the possibility that there is a race condition.
Any of these situations would cause crashes in the 0-3% range.

Firebase App configuration crash

I have a custom keyboard for iOS that uses Firebase for analytics. The Firebase app configuration is done at the initializer with a dispatch_once clause with the token as a global variable.
var token: dispatch_once_t = 0
class KeyboardViewController: UIInputViewController {
// ..
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
dispatch_once(&token) {
FIRApp.configure()
} // line 90
}
// ..
}
This is working fine but I am receiving many crash reports that indicate crashes on many devices when the app is configured. I am stuck for days trying to figure out the cause. Here is a part of one of the crash reports stack trace:
Exception Type: EXC_CRASH (SIGQUIT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Quit: 3
Termination Reason: Namespace SIGNAL, Code 0x3
Terminating Process: launchd [1]
Triggered by Thread: 0
Thread 0 name:
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x000000018fab6338 __semwait_signal_nocancel + 8
1 libsystem_c.dylib 0x000000018f9e20dc nanosleep$NOCANCEL + 200 (nanosleep.c:104)
2 libsystem_c.dylib 0x000000018fa0568c sleep$NOCANCEL + 44 (sleep.c:62)
3 libsystem_dnssd.dylib 0x000000018fa6e7d4 ConnectToServer + 832 (dnssd_clientstub.c:607)
4 libsystem_dnssd.dylib 0x000000018fa6ff44 DNSServiceCreateConnection + 76 (dnssd_clientstub.c:1785)
5 libsystem_network.dylib 0x000000018fb2d318 __nw_resolver_set_update_handler_block_invoke + 872 (resolver.m:1031)
6 libdispatch.dylib 0x000000018f9711c0 _dispatch_client_callout + 16 (object.m:455)
7 libdispatch.dylib 0x000000018f97e860 _dispatch_barrier_sync_f_invoke + 84 (queue.c:3457)
8 libsystem_network.dylib 0x000000018fb2ce78 nw_resolver_set_update_handler + 208 (resolver.m:1275)
9 SystemConfiguration 0x0000000190f8a16c __SCNetworkReachabilityRestartResolver + 260 (SCNetworkReachability.c:1711)
10 SystemConfiguration 0x0000000190f891c8 __SCNetworkReachabilitySetDispatchQueue + 764 (SCNetworkReachability.c:1823)
11 SystemConfiguration 0x0000000190f88ccc SCNetworkReachabilityScheduleWithRunLoop + 504 (SCNetworkReachability.c:1586)
12 CustomKeyboard 0x000000010013f630 -[FIRReachabilityChecker start] + 196
13 CustomKeyboard 0x000000010013abac -[FIRNetwork init] + 156
14 CustomKeyboard 0x0000000100132e28 -[FIRClearcutLogger init] + 416
15 CustomKeyboard 0x0000000100132c68 __35+[FIRClearcutLogger sharedInstance]_block_invoke + 36
16 libdispatch.dylib 0x000000018f9711c0 _dispatch_client_callout + 16 (object.m:455)
17 libdispatch.dylib 0x000000018f971fb4 dispatch_once_f + 56 (once.c:57)
18 CustomKeyboard 0x0000000100132c40 +[FIRClearcutLogger sharedInstance] + 108
19 CustomKeyboard 0x0000000100137214 +[FIRApp initClearcut] + 60
20 CustomKeyboard 0x0000000100136688 +[FIRApp configureDefaultAppWithOptions:sendingNotifications:] + 132
21 CustomKeyboard 0x000000010013643c +[FIRApp configure] + 316
22 libdispatch.dylib 0x000000018f9711c0 _dispatch_client_callout + 16 (object.m:455)
23 libdispatch.dylib 0x000000018f971fb4 dispatch_once_f + 56 (once.c:57)
24 CustomKeyboard 0x00000001000e314c _TFC19CustomKeyboard22KeyboardViewControllercfT7nibNameGSqSS_6bundleGSqCSo8NSBundle__S0_ + 1500 (KeyboardViewController.swift:90)
25 CustomKeyboard 0x00000001000e3270 _TToFC19CustomKeyboard22KeyboardViewControllercfT7nibNameGSqSS_6bundleGSqCSo8NSBundle__S0_ + 112 (KeyboardViewController.swift:0)
26 UIKit 0x00000001971f7688 -[_UIViewServiceViewControllerOperator __createViewController:withContextToken:fbsDisplays:appearanceSerializedRepresentations:legacyAppearance:traitCollection:initialInterfaceOrientation:hostAccessibilityServerPort:canShowTextServices:replyHandler:] + 2216 (UIViewServiceViewControllerOperator.m:1732)
27 CoreFoundation 0x0000000190aee160 __invoking___ + 144
28 CoreFoundation 0x00000001909e1c3c -[NSInvocation invoke] + 284 (NSForwarding.m:2948)
29 CoreFoundation 0x00000001909e66ec -[NSInvocation invokeWithTarget:] + 60 (NSForwarding.m:3019)
Apparently, the call trace after calling FIRApp.configure() is going through system libraries.
One observation from the stack trace is that the crash has something to do with checking the reachability of the device. However, I tried to reproduce a scenario where there is no internet connection but it's working fine.
Please note that all the crashes are happening on iOS 10 and most of them on iPhone 6.
Any help to figure out the cause of the crashes would be appreciated.
It is not recommended to use Firebase Analytics in an extension as the SDK does not support extension well. App extensions have limited functionalities compared to a full app so Firebase Analytics may not work well under some conditions, like the network in this case. The team is looking into supporting extensions better later.
It seems like the network is not available on custom keyboard as stated by Apple
"By default, a keyboard has no network access and cannot share a
container with its containing app. To enable these things, set the
value of the RequestsOpenAccess Boolean key in the Info.plist file to
YES. Doing this expands the keyboard’s sandbox, as described in
Designing for User Trust."
https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/CustomKeyboard.html#//apple_ref/doc/uid/TP40014214-CH16-SW1

SKProduct crash - only in store version of app

I have a swift app with below SKProduct code
func validateProductIdentifiers() {
let identifiers:NSSet = NSSet(array: kProductIdentifiers)
let productRequest = SKProductsRequest(productIdentifiers: identifiers)
productRequest.delegate = self
productRequest.start()
}
func productsRequest(request: SKProductsRequest!, didReceiveResponse response: SKProductsResponse!) {
let product:SKProduct = response.products[0] as SKProduct
homeView!.stopActivityAnimating()
loadBulletBuy()
bulletBuy!.loadBuyData(response)
}
I have been testing this app is my device for close to a month and the app never failed/crashed during a call to this method.
Now my app is live and I found my app is crashing in above method. Crash log from my device
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 FrontLine 0x000000010016654c #objc FrontLine.GameViewController.productsRequest (FrontLine.GameViewController)(ObjectiveC.SKProductsRequest!, didReceiveResponse : ObjectiveC.SKProductsResponse!) -> () (GameViewController.swift:0)
1 StoreKit 0x0000000186638dac __34-[SKProductsRequest _handleReply:]_block_invoke + 540
2 libdispatch.dylib 0x0000000192cb53a8 _dispatch_call_block_and_release + 20
3 libdispatch.dylib 0x0000000192cb5368 _dispatch_client_callout + 12
4 libdispatch.dylib 0x0000000192cb997c _dispatch_main_queue_callback_4CF + 928
5 CoreFoundation 0x0000000181eddfa0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
6 CoreFoundation 0x0000000181edc048 __CFRunLoopRun + 1488
7 CoreFoundation 0x0000000181e090a0 CFRunLoopRunSpecific + 392
8 GraphicsServices 0x000000018afa35a0 GSEventRunModal + 164
9 UIKit 0x000000018673aaa0 UIApplicationMain + 1484
10 FrontLine 0x0000000100189640 main (AppDelegate.swift:0)
11 libdyld.dylib 0x0000000192cdea04 start + 0
I did some searching and found that it may be due to deallocation of delegate and in my case a VC. I am trying out a new solution now.
But I am not able to understand why the app never crashed in my test runs and crashing in production alone.
I tried to install my dev version of app and the app runs smooth where as if I install the app store version it crashes.
Any insight on how I can prevent such failures would be helpful
Thanks
The issue disappeared after like 3 hours in production.Looks like some payment process lags behind actual app release.

Resources