SwiftJWT crashes iOS App on JWT.init() call - ios

The following code crashes on iPad mini 2 / 3 only when executed from the AppStore distributed executable.
let jwtVerifier = JWTVerifier.es512(publicKey: publicKey.data(using: .utf8)!)
do {
let parsedJwt = try JWT<LicenseJWTClaims>(jwtString: jwt, verifier: jwtVerifier) // <== crashes here
return License(jwt: parsedJwt, raw_jwt_string: jwt)
} catch {
}
// LicenseJWTClaims for reference
internal struct LicenseJWTClaims: Claims {
let exp: Date?
let nbf: Date?
let iat: Date?
let licenseKey: String?
}
The code works just fine on every device when installed via XCode. The App also works on 'normal' (not mini) iPads when installed from the App Store.
How would you go on analysing this issue? Do you maybe even have a fix available?
Find the relevant part of the crash log below:
Thread 0 name: Dispatch queue: com.apple.avfoundation.metadataoutput.objectqueue
Thread 0 Crashed:
0 libswiftCore.dylib 0x00000001b1b33b00 specialized _fatalErrorMessage+ 2112256 (_:_:file:line:flags:) + 296
1 libswiftCore.dylib 0x00000001b1b33b00 specialized _fatalErrorMessage+ 2112256 (_:_:file:line:flags:) + 296
2 libswiftCore.dylib 0x00000001b1b65300 specialized _NativeDictionary.bridged+ 2315008 () + 288
3 libswiftCore.dylib 0x00000001b19b1f70 _NativeDictionary.bridged+ 532336 () + 20
4 CryptorECC 0x0000000100564958 specialized ECPublicKey.init(der:) + 51544 (ECPublicKey.swift:144)
5 CryptorECC 0x0000000100564240 ECPublicKey.__allocating_init(key:) + 49728 (ECPublicKey.swift:93)
6 SwiftJWT 0x00000001008a36d0 BlueECVerifier.verify(signature:for:) + 30416 (BlueECDSA.swift:99)
7 SwiftJWT 0x00000001008a34a8 BlueECVerifier.verify(jwt:) + 29864 (BlueECDSA.swift:84)
8 SwiftJWT 0x00000001008a3884 protocol witness for VerifierAlgorithm.verify(jwt:) in conformance BlueECVerifier + 30852 (<compiler-generated>:0)
9 SwiftJWT 0x00000001008b3200 JWT.init(jwtString:verifier:) + 94720 (JWT.swift:73)
10 Eliah 0x00000001004d25e4 LicenseValidator.constructLicense(with:) + 255460 (License.swift:64)
11 Eliah 0x00000001004d3eb4 LicenseViewController.licenseScanned(_:) + 261812 (LicenseViewController.swift:35)
12 Eliah 0x00000001004d518c partial apply for implicit closure #2 in implicit closure #1 in LicenseViewController.loadView() + 266636 (<compiler-generated>:0)
13 Eliah 0x00000001004d6c9c specialized LicenseScanView.metadataOutput(_:didOutput:from:) + 273564 (LicenseScanView.swift:0)
14 Eliah 0x00000001004d616c #objc LicenseScanView.metadataOutput(_:didOutput:from:) + 270700 (<compiler-generated>:0)
15 AVFoundation 0x000000018a40ac2c -[AVCaptureMetadataOutput _processSampleBuffer:] + 1284
16 AVFoundation 0x000000018a40a520 __46-[AVCaptureMetadataOutput _updateRemoteQueue:]_block_invoke + 100
17 CoreMedia 0x00000001878c9118 __FigRemoteOperationReceiverCreateMessageReceiver_block_invoke + 280
18 CoreMedia 0x00000001878e6718 __FigRemoteQueueReceiverSetHandler_block_invoke.2 + 224
19 libdispatch.dylib 0x0000000183d9c7d4 _dispatch_client_callout + 16
20 libdispatch.dylib 0x0000000183d4101c _dispatch_continuation_pop$VARIANT$mp + 412
21 libdispatch.dylib 0x0000000183d50fa8 _dispatch_source_invoke$VARIANT$mp + 1308
22 libdispatch.dylib 0x0000000183d451f0 _dispatch_lane_serial_drain$VARIANT$mp + 284
23 libdispatch.dylib 0x0000000183d45e74 _dispatch_lane_invoke$VARIANT$mp + 480
24 libdispatch.dylib 0x0000000183d49eec _dispatch_main_queue_callback_4CF$VARIANT$mp + 784
25 CoreFoundation 0x00000001842efb20 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
26 CoreFoundation 0x00000001842eaa58 __CFRunLoopRun + 1924
27 CoreFoundation 0x00000001842e9fb4 CFRunLoopRunSpecific + 436
28 GraphicsServices 0x00000001864eb79c GSEventRunModal + 104
29 UIKitCore 0x00000001b07efc38 UIApplicationMain + 212
30 Eliah 0x0000000100499b88 main + 23432 (AppDelegate.swift:5)
31 libdyld.dylib 0x0000000183dad8e0 start + 4

Those are both old devices limited to iOS 12. It's not clear if you're able to get it to work on other iOS 12 devices, but I'd look at the common threads of OS version and architecture to see if you can spot a pattern.
Logically speaking, since it's only happening via distributions on the app store, either it's something on Apple's end and unlikely to be fixed since those devices are so old, or its something with the way you're publishing the binary to the app store. Logically, fiddling with the archive options in xcode would be something to try.
I think if it were me I would consider dropping support for those devices and moving on now that 81% of devices are running iOS 14. (But I can't speak for your situation).
In any case, good luck. That's a tough problem.

CryptorEEC is open source. The last call to the stack that isn't a system framework is ECPublicKey.swift:144.
As you can see from that link, it's creating a dictionary with this value kSecAttrKeyTypeECSECPrimeRandom. According to the next call in the stack, this is causing the crash.
I searched for kSecAttrKeyTypeECSECPrimeRandom on Google and I found this question on SO.
This answer suggests that a key larger than 256 is too big for ECSEC.
This is an old question with old answers, which leads me to believe it's crashing on older devices with older iOS versions because support for larger keys was introduced in iOS 13 or later, or in devices with Secure Enclave (I'm not sure).
Since I don't know how you're using this encrypted token, I can't make a suggestion on how to fix this, but I hope it's at least enough information for you to make a decision.

Although none of the answers really solved the issue, I still want to share the debugging approach and the final solution.
Analysing this issue
The development build weren't producing the bug. JWT tokens could be parsed just fine. To analyse the issue, I was able to create an Ad Hoc distribution and distribute it via a static web server.
Installing this way, the same issue were happening like with the App Store build.
By the way: it was irrelevant 'Rebuild from Bitcode' or not.
My Solution
...was to just switch to RSA signed tokens. Not my favourite, but somewhat practical to also support these devices.

Related

Can't symbolicate crash logs

I experiencing a crash in my app:
Thread 0 name:
Thread 0 Crashed:
0 LogoQuizAC 0x0000000104705218 __hidden#563_ + 0 (__hidden#957_:0)
1 LogoQuizAC 0x0000000104705218 _hidden#18_ + 592 (__hidden#957_:135)
2 LogoQuizAC 0x000000010470503c __hidden#564_ + 48 (__hidden#456_:0)
3 LogoQuizAC 0x000000010470503c _hidden#18_ + 116 (__hidden#957_:135)
4 LogoQuizAC 0x00000001046fcd6c _hidden#17_ + 504 (__hidden#454_:96)
5 LogoQuizAC 0x00000001046fcea0 _hidden#20_ + 36 (__hidden#456_:0)
6 Foundation 0x0000000182770b20 __NSFireTimer + 68 (NSTimer.m:270)
7 CoreFoundation 0x0000000181355fa0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 32 (CFRunLoop.c:1807)
8 CoreFoundation 0x0000000181355ba0 __CFRunLoopDoTimer + 1064 (CFRunLoop.c:2415)
9 CoreFoundation 0x0000000181354ffc __CFRunLoopDoTimers + 328 (CFRunLoop.c:2575)
10 CoreFoundation 0x000000018134eee4 __CFRunLoopRun + 1936 (CFRunLoop.c:3090)
11 CoreFoundation 0x000000018134e21c CFRunLoopRunSpecific + 600 (CFRunLoop.c:3242)
12 GraphicsServices 0x0000000198f18784 GSEventRunModal + 164 (GSEvent.c:2259)
13 UIKitCore 0x0000000183d8eee8 -[UIApplication _run] + 1072 (UIApplication.m:3253)
14 UIKitCore 0x0000000183d9475c UIApplicationMain + 168 (UIApplication.m:4707)
15 LogoQuizAC 0x000000010453a404 main + 68 (RLockedCell.swift:21)
16 libdyld.dylib 0x000000018100e6b0 start + 4
I tried almost everything but can symbolicate the crash.
I tried using symbolicatecrash followed by these posts:
(_hidden#919_:0) inside crash symbolication file
Why aren't the crashlogs from Testflight symbolicating in Xcode?
Xcode Crash Organizer does Not Symbolicate .xccrashpoint Files
How to symbolicate crash log with Xcode 8?
how Symbolicate a crash file using xcarchive
How to symbolicate crash log Xcode?
But without any success.
What am I doing wrong? How can I figure out what causing the crash?
The good news that it is crashing in your code, not in Operating Systems or Library code, so you have a good chance to debug it. Your code that is crashing is running off a timer. Sometimes these bugs are seen because in testing, you are just testing the app. But in the real world, those timers fire when you are not expecting them.
For example, someone ran your app, then put it into the background when using another app, or for example they received a phone call whilst using the app. If you attach the full contents of the .crash file, it will give more information on the cause of the crash.
Another thing you can do is place asserts into your code, such as in your timer callback functions for each object you are relying on being non-null.
You may find that your app is trying to draw onto the screen but is in the background. This is a common reason for a crash seen in the field for games that use timers. That may sound like a generalisation but it is a suggestion to try and make you think differently about the real world environment your customers face which can the reason for the failure.

What is the cause of an iOS 12 ".cold.1" viewcontroller crash, pertaining to CoreData?

I have a crash in my iOS application that appears to be unique to iOS 12 only. This crash started happening when Xcode 11.3 was released.
The stack trace is as follows
Crashed: com.apple.main-thread
0 libsystem_kernel.dylib 0x20148b0dc __pthread_kill + 8
1 libsystem_pthread.dylib 0x201504094 pthread_kill$VARIANT$mp + 380
2 libsystem_c.dylib 0x2013e3ea8 abort + 140
3 Field Portal 0x100d9cc74 -[InventoryViewController initializeData].cold.1 + 4305833076
4 Field Portal 0x100c1227c -[PSICoreDataController saveViewContext] + 73 (PSICoreDataController.m:73)
5 CoreData 0x2044832b0 developerSubmittedBlockToNSManagedObjectContextPerform + 156
6 libdispatch.dylib 0x20132d7d4 _dispatch_client_callout + 16
7 libdispatch.dylib 0x2012db008 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1068
8 CoreFoundation 0x201880b20 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
9 CoreFoundation 0x20187ba58 __CFRunLoopRun + 1924
10 CoreFoundation 0x20187afb4 CFRunLoopRunSpecific + 436
11 GraphicsServices 0x203a7c79c GSEventRunModal + 104
12 UIKitCore 0x22e0dcc38 UIApplicationMain + 212
13 Field Portal 0x100c1939c main + 14 (main.m:14)
14 libdyld.dylib 0x20133e8e0 start + 4
InventoryViewController is a very specific view controller nested VERY deeply within the application, and is not used by any user of my app (yes, I know this).
It seems like what is happening is when I call a save on my primary viewContext, the iOS runtime is somehow initializing InventoryViewController on its own, triggering this function, which results in a crash.
InitializeData itself merely executes a simple NSFetchRequest against the main CoreData context, and if I access this view through normal means, it will not crash on the impacted hardware/OS.
What I don't understand is WHY is iOS doing this? This view controller is never accessed by users, and it is never called directly by any of my code.
Furthermore, this code has not changed in almost a calendar year, and suddenly started happening only on these new builds, and only on iOS 12.
I've found this issue impossible to debug, and would welcome any insight on methodologies for research and analysis on how I can figure out what the cause of this issue is.

Does Crashlytics encounter assertionFailure as crash?

I'm a bit confused and can't find proper information about this case. As we all know from docs:
Use this function to stop the program, without impacting the
performance of shipping code, when control flow is not expected to
reach the call—for example, in the default case of a switch where you
have knowledge that one of the other cases must be satisfied. To
protect code from invalid usage in Release builds, see
preconditionFailure(_:file:line:).
However, I'm getting crash report in Crashlytics when my asserionFailure fires.
Crashed: com.apple.main-thread
0 libswiftCore.dylib 0x1b0c15efc specialized _assertionFailure(_:_:file:line:flags:) + 440
1 libswiftCore.dylib 0x1b0a316b8 assertionFailure(_:file:line:) + 96
2 OneFit 0x100a3d238 AdditionalUserInfoRouter.enqueueRoute(with:animated:completion:) + 64 (AdditionalUserInfoRouter.swift:64)
3 OneFit 0x100a53040 protocol witness for MVVMRouter.enqueueRoute(with:animated:completion:) in conformance AdditionalUserInfoRouter + 4374458432 (<compiler-generated>:4374458432)
4 OneFit 0x100638224 MVVMRouter.enqueueRoute(with:) + 32 (MVVMRouter.swift:32)
5 OneFit 0x100a6a6c8 closure #2 in AdditionalUserInfoViewModel.close() + 132 (AdditionalUserInfoViewModel.swift:132)
6 OneFit 0x100a676a0 thunk for #escaping #callee_guaranteed (#guaranteed [Subscription]) -> (#error #owned Error) + 4374541984 (<compiler-generated>:4374541984)
7 OneFit 0x100a6fb94 partial apply for thunk for #escaping #callee_guaranteed (#guaranteed [Subscription]) -> (#error #owned Error) + 4374576020 (<compiler-generated>:4374576020)
8 PromiseKit 0x10344d048 $s10PromiseKit8ThenablePAAE4done2on5flags_AA0A0CyytGSo17OS_dispatch_queueCSg_8Dispatch0J13WorkItemFlagsVSgy1TQzKctFyAA6ResultOyARGcfU_yycfU_ + 64
9 PromiseKit 0x103426614 $sIeg_IeyB_TR + 28
10 libdispatch.dylib 0x1a35a9610 _dispatch_call_block_and_release + 24
11 libdispatch.dylib 0x1a35aa184 _dispatch_client_callout + 16
12 libdispatch.dylib 0x1a355c1d0 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1044
13 CoreFoundation 0x1a385a3c4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
14 CoreFoundation 0x1a38553b8 __CFRunLoopRun + 2004
15 CoreFoundation 0x1a38548bc CFRunLoopRunSpecific + 464
16 GraphicsServices 0x1ad6c0328 GSEventRunModal + 104
17 UIKitCore 0x1a78ea6d4 UIApplicationMain + 1936
18 OneFit 0x1003b3784 main + 39 (AppDelegate.swift:39)
19 libdyld.dylib 0x1a36df460 start + 4
Does Crashlytics logs asserts as crashes or I have some real crash?
UPD: Firebase/Crashlytics support response:
I don't know of any particular Crashlytics-related behavior around
assertionFailure, and unless it's terminating the main app thread I
would not expect us to view it as a crash. I see there's already an
answer on the stackoverflow post - does that clear things up?
Assertions are not supposed to be enabled in release builds with -O optimisations level. This means that in final release code there will be like a blank line and so Crashlytics has nothing to crash at.
Double-check your target's build settings, if you created it from scratch or copied it from debug you may have left assertions enabled.
From docs:
In playgrounds and -Onone builds (the default for Xcode’s Debug
configuration), stop program execution in a debuggable state after
printing message.
In -O builds, has no effect.
In -Ounchecked builds, the optimizer may assume that this function is
never called. Failure to satisfy that assumption is a serious
programming error.

_UIDelayedPresentationContext beginDelayedPresentation causing crashes on iOS

I have been getting rather strange crash reports from my live app with stack traces like the following:
Thread 0: Crashed: com.apple.main-thread
0 libobjc.A.dylib 0x38af7942 realizeClass(objc_class*) + 117
1 libsystem_malloc.dylib 0x390dbef5 szone_malloc_should_clear + 1376
2 libobjc.A.dylib 0x38af976f lookUpImpOrForward + 74
3 libobjc.A.dylib 0x38af1feb _class_lookupMethodAndLoadCache3 + 34
4 libobjc.A.dylib 0x38af1db9 _objc_msgSend_uncached + 24
5 UIKit 0x30e571bf __57-[_UIDelayedPresentationContext beginDelayedPresentation]_block_invoke + 26
6 libdispatch.dylib 0x38fd9d07 _dispatch_client_callout + 22
7 libdispatch.dylib 0x38fe2803 _dispatch_source_invoke$VARIANT$mp + 262
8 libdispatch.dylib 0x38fe073d _dispatch_main_queue_callback_4CF$VARIANT$mp + 188
9 CoreFoundation 0x2e3ef819 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
10 CoreFoundation 0x2e3ee0ed __CFRunLoopRun + 1300
11 CoreFoundation 0x2e358c27 CFRunLoopRunSpecific + 522
12 CoreFoundation 0x2e358a0b CFRunLoopRunInMode + 106
13 GraphicsServices 0x3302c283 GSEventRunModal + 138
14 UIKit 0x30bfc049 UIApplicationMain + 1136
This is rather mysterious because neither the main thread nor any of the other live threads in the reports seem to imply that this is caused by my code, though of course I am skeptical of this.
This seems to be a rather common crash according to the number of reports I receive from Crashlytics, yet I have not been able to reproduce it on my own devices. I suspect this is probably related to some memory management issues because the various crashes always end up being some bad pointers being sent messages.
This always happens on this thread and following the -[_UIDelayedPresentationContext beginDelayedPresentation]_block_invoke call. This is obviously a private class being referenced from within some Apple framework, however I am at a loss to figure out exactly which one could be calling this.
The app is an educational game and I suspect this could be related to the GameKit API (particularly the Game Center authentication dialogs).
All of these crashes have been happening exclusively on iOS 7 and on iPad only. The app is universal so it is interesting to see that iPhone users seem to be unaffected.
Does anybody have any previous experience with these private classes that could give me some hints?

Interpreting iPhone Crash Log / Stack Trace

I'm using the TestFlight SDK and have received several crash reports identical to this one. However, I'm having trouble understanding it, and what the underlying cause of the crash is from the reports?
Exception
SIGSEGV
2 libsystem_c.dylib 0x32862e92 _sigtramp + 42
3 Foundation 0x33750d1c -[NSError dealloc] + 60...
Exception reason
SIGSEGV
Stacktrace
0 MyAppName 0x0013faba testflight_backtrace + 382
1 MyAppName 0x00140708 TFSignalHandler + 264
2 libsystem_c.dylib 0x32862e92 _sigtramp + 42
3 Foundation 0x33750d1c -[NSError dealloc] + 60
4 libobjc.A.dylib 0x39230488 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 168
5 CoreFoundation 0x31de9440 _CFAutoreleasePoolPop + 16
6 Foundation 0x33751f7a -[NSAutoreleasePool drain] + 122
7 CoreData 0x35e0a4b2 -[NSManagedObjectContext save:] + 1210
8 MyAppName 0x000b7168 MR_swapMethodsFromClass + 18076
9 CoreData 0x35e0dbc0 developerSubmittedBlockToNSManagedObjectContextPerform + 88
10 libdispatch.dylib 0x335974b6 _dispatch_client_callout + 22
11 libdispatch.dylib 0x33598dca _dispatch_main_queue_callback_4CF$VARIANT$up + 226
12 CoreFoundation 0x31e79f3a __CFRunLoopRun + 1290
13 CoreFoundation 0x31decebc CFRunLoopRunSpecific + 356
14 CoreFoundation 0x31decd48 CFRunLoopRunInMode + 104
15 GraphicsServices 0x36e092ea GSEventRunModal + 74
16 UIKit 0x320db2f8 UIApplicationMain + 1120
17 MyAppName 0x00099122 main (main.m:17)
18 MyAppName 0x000990d7 start + 39
Additional details:
Users report this crash happens 1-2 seconds after the app starts
The app uses Core Data and MagicalRecord (which is where the MR_swapMethodsFromClass method comes from)
I can't reproduce this issue on any test devices when running from Xcode (iPhone 3GS, iPhone 4, or iPhone 5) running various iOS versions (iOS 5.1, 6.0, 6.1)
EDIT
Still working on solving this issue... I've been able to recreate it (but not with a debugger attached).
Here's the strangest part-- if a user has an older version of the app and installs an update (distributed via Test Flight), they get this error.
However, if they first delete the old app and install the update, the error doesn't occur.
Let's walk through it:
0 MyAppName 0x0013faba testflight_backtrace + 382
1 MyAppName 0x00140708 TFSignalHandler + 264
That's TestFlight. This is after the crash has happened, so it's certainly not the cause.
2 libsystem_c.dylib 0x32862e92 _sigtramp + 42
This is the point at which we caught the crash. "sigtramp" is the signal "trampoline." That's a fancy way of saying "I caught a signal (crash) and now I'm going to bounce to somewhere else in the code."
3 Foundation 0x33750d1c -[NSError dealloc] + 60
Ah. This is important. We crashed while deallocating an NSError. That means the NSError was over-released or under-retained.
4 libobjc.A.dylib 0x39230488 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 168
5 CoreFoundation 0x31de9440 _CFAutoreleasePoolPop + 16
6 Foundation 0x33751f7a -[NSAutoreleasePool drain] + 122
Sad… it manifested while draining the autorelease pool. That means the actual bug could be a long way from here. But at least we know the type of the object. NSZombies could be of use to try to find the specific object.
7 CoreData 0x35e0a4b2 -[NSManagedObjectContext save:] + 1210
And the autorelease pool was draining during a MOC save. That suggests it's probably related to your Core Data code. It's at least where you'd look first.
The things to remember are:
The bug is almost certainly in your code.
If it's not in your code, it's probably in Magical Record
Do not assume it is in Core Data. That is the least likely place for the bug given this stack.
Here's the strangest part-- if a user has an older version of the app and installs an update (distributed via Test Flight), they get this error.
However, if they first delete the old app and install the update, the error doesn't occur.
Probably in your upgrade code then. Most likely in the Core Data migration stuff. Audit every use of NSError in that area of code. Eliminate all compiler and analyzer warnings. And try NSZombies if its reproducible.
You should try to add a model version to your data model. It worked for me, i had a similar Magical-Record-related issue.

Resources