Crash in cacheKey method
Hi, I'm getting occasional crash reports from the cacheKey method in FXImageView... Anyone has an idea how to resolve?? See crash report below..
1 libsystem_platform.dylib _OSAtomicCompareAndSwap32Barrier + 14 2 libobjc.A.dylib lookUpImpOrForward + 75 3 libobjc.A.dylib _class_lookupMethodAndLoadCache3 + 35 4 libobjc.A.dylib _objc_msgSend_uncached + 25 5 Foundation __NSDescriptionWithLocaleFunc + 53 6 CoreFoundation __CFStringAppendFormatCore + 5623 7 CoreFoundation __CFStringCreateWithFormatAndArgumentsAux + 77 8 Foundation -[NSPlaceholderString initWithFormat:locale:arguments:] + 131 9 Foundation +[NSString stringWithFormat:] + 61 10 APPNAME -FXImageView cacheKey 11 APPNAME -FXImageView processImage 12 APPNAME -FXImageOperation main 13 Foundation -[__NSOperationInternal _start:] + 773
What is the actual exception?
A simple fix is probably just to use a custom cacheKey of your own specification, but I'd like to know what the cause of this was.
Exception Type: SIGSEGV Exception Codes: SEGV_ACCERR at 0xf000000c Crashed Thread: 21
The symbolised thread is below: Thread 21 Crashed: 0 libobjc.A.dylib 0x37c09b66 _objc_msgSend + 6 1 Foundation 0x2de7c659 _NSDescriptionWithLocaleFunc + 53 2 CoreFoundation 0x2d53abef __CFStringAppendFormatCore + 5623 3 CoreFoundation 0x2d4a9c4d __CFStringCreateWithFormatAndArgumentsAux + 77 4 Foundation 0x2de7c607 -[NSPlaceholderString initWithFormat:locale:arguments:] + 131 5 Foundation 0x2de7c509 +[NSString stringWithFormat:] + 61 6 APPNAME 0x000c796d -FXImageView cacheKey 7 APPNAME 0x000c7cb1 -FXImageView processImage 8 APPNAME 0x000c71a7 -FXImageOperation main 9 Foundation 0x2de93aa5 -[__NSOperationInternal _start:] + 773 10 Foundation 0x2df3796d __NSOQSchedule_f + 61 11 libdispatch.dylib 0x380f74b7 _dispatch_async_redirect_invoke + 111 12 libdispatch.dylib 0x380f87d9 _dispatch_root_queue_drain + 225 13 libdispatch.dylib 0x380f89c5 _dispatch_worker_thread2 + 57 14 libsystem_pthread.dylib 0x38222dff __pthread_wqthread + 299
Note the line 232 in cacheKey is "NSStringFromCGSize(shadowOffset)," in the following return statement: return [NSString stringWithFormat:@"%@%@%.2f%.2f_%.2f_%@%@%.2f_%.2f_%i", _imageContentURL ?: [self imageHash:_originalImage], NSStringFromCGSize(self.bounds.size), _reflectionGap, _reflectionScale, _reflectionAlpha, [self colorHash:_shadowColor], NSStringFromCGSize(_shadowOffset), _shadowBlur, _cornerRadius, self.contentMode];
Hi, were you able to find the root cause of this crash? Any suggestions how to solve it? It's currently my second-frequent crash in the apps I have with FXImageView incorporated....
I haven't been able to reproduce the issue yet, but as a workaround, try setting the cacheKey explicitly.
Yes, I also have difficulties reproducing it, but it still shows up in my crash reporting. I think I'm just going to try to send out a build with a modified cacheKey: Will let you know whether that solved it... return [NSString stringWithFormat:@"%@", [_imageContentURL absoluteString] ?: [self imageHash:_originalImage]];
Sometimes I can reproduce a crash in the cacheKey method, at line 202: NSStringFromCGSize(_shadowOffset) but it's not a SIGSEGV it's an EXC BAD ACCESS. The stack trace referes to FXImageOperation:
- (void)main
{
@autoreleasepool
{
[_target processImage];
}
}
Maybe this information can help to fix the problem?
Hi
Also have crashlytics report from some user. Someone have an idea?
Crashed: NSOperationQueue 0x17d095d0 :: NSOperation 0x17db2aa0 (QOS: UTILITY) Thread : Crashed: NSOperationQueue 0x17d095d0 :: NSOperation 0x17db2aa0 (QOS: UTILITY) 0 libobjc.A.dylib 0x224a3ac6 objc_msgSend + 5 1 Foundation 0x235073b1 _NSDescriptionWithStringProxyFunc + 48 2 CoreFoundation 0x22cc30dd __CFStringAppendFormatCore + 7132 3 CoreFoundation 0x22cc14e1 _CFStringCreateWithFormatAndArgumentsAux2 + 80 4 Foundation 0x2342ea05 -[NSPlaceholderString initWithFormat:locale:arguments:] + 144 5 Foundation 0x2342e8fd +[NSString stringWithFormat:] + 60 6 Poses Model 0x136175 -FXImageView cacheKey 7 Poses Model 0x1364d5 -FXImageView processImage
Hi, same problem.
0 CoreFoundation 0x18166afe0 __exceptionPreprocess 1 libobjc.A.dylib 0x1800cc538 objc_exception_throw 2 CoreFoundation 0x181671ef4 __methodDescriptionForSelector 3 CoreFoundation 0x18166ef54 forwarding 4 CoreFoundation 0x18156ad4c _CF_forwarding_prep_0 5 Foundation 0x1820c324c -[NSURL(NSURL) description] 6 Foundation 0x182056584 _NSDescriptionWithLocaleFunc 7 CoreFoundation 0x18162c8bc __CFStringAppendFormatCore 8 CoreFoundation 0x18162a78c _CFStringCreateWithFormatAndArgumentsAux2 9 Foundation 0x1820563d8 +[NSString stringWithFormat:] 10 MyApp 0x100070fd4 -[FXImageView cacheKey] (FXImageView.m:205) 11 MyApp 0x1000713b8 -[FXImageView processImage] (FXImageView.m:265) 12 MyApp 0x100070664 -[FXImageOperation main] (FXImageView.m:75) 13 Foundation 0x18206eb28 -[__NSOperationInternal _start:] 14 Foundation 0x18213bbb0 __NSOQSchedule_f 15 libdispatch.dylib 0x1805229a0 _dispatch_client_callout 16 libdispatch.dylib 0x180530ad4 _dispatch_queue_serial_drain 17 libdispatch.dylib 0x1805262cc _dispatch_queue_invoke 18 libdispatch.dylib 0x180532a50 _dispatch_root_queue_drain 19 libdispatch.dylib 0x1805327d0 _dispatch_worker_thread3 20 libsystem_pthread.dylib 0x18072b100 _pthread_wqthread 21 libsystem_pthread.dylib 0x18072acac start_wqthread
Hi Nick,
Same here, but it happens with Xcode 9.0.1 with iOS 11 on iPhone X (simulator) only; i.e. crashes consistently. However, it works fine on iPhone 6/7/8 and 6+/7+/8+ iOS 10.x and 11.x (simulators).
Main Thread Checker: UI API called on a background thread: -[UIView bounds]
PID: 15217, TID: 9896264, Thread name: (none), Queue name: NSOperationQueue 0x60400022eaa0 (QOS: UNSPECIFIED), QoS: 0
Backtrace:
4 App 0x000000010070f657 -[FXImageView cacheKey] + 215
5 App 0x000000010070fce4 -[FXImageView processImage] + 52
6 App 0x000000010070e96f -[FXImageOperation main] + 63
7 Foundation 0x0000000103d1acd6 -[__NSOperationInternal _start:] + 778
8 libdispatch.dylib 0x000000010762743c _dispatch_client_callout + 8
9 libdispatch.dylib 0x000000010762caf4 _dispatch_block_invoke_direct + 592
10 libdispatch.dylib 0x000000010762743c _dispatch_client_callout + 8
11 libdispatch.dylib 0x000000010762caf4 _dispatch_block_invoke_direct + 592
12 libdispatch.dylib 0x000000010762c884 dispatch_block_perform + 109
13 Foundation 0x0000000103d16ce4 __NSOQSchedule_f + 342
14 libdispatch.dylib 0x000000010762743c _dispatch_client_callout + 8
15 libdispatch.dylib 0x000000010762d856 _dispatch_continuation_pop + 967
16 libdispatch.dylib 0x000000010762bc86 _dispatch_async_redirect_invoke + 780
17 libdispatch.dylib 0x00000001076331f9 _dispatch_root_queue_drain + 772
18 libdispatch.dylib 0x0000000107632e97 _dispatch_worker_thread3 + 132
19 libsystem_pthread.dylib 0x0000000107bbb5a2 _pthread_wqthread + 1299
20 libsystem_pthread.dylib 0x0000000107bbb07d start_wqthread + 13
Any idea on how to trace that?
I'm not sure if that would help, but this part of the same log. I do not know if the cause is in cacheKey or in UIImageView.setPosition. If you need more information, let me know, I'll be happy to help.
2017-11-02 17:43:15.303185-0400 App[15217:9896139] *** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [156.833 nan]'
0 CoreFoundation 0x00000001070ec1cb __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000106600f41 objc_exception_throw + 48
2 CoreFoundation 0x0000000107160b95 +[NSException raise:format:] + 197
3 QuartzCore 0x000000010390e1bc _ZN2CA5Layer12set_positionERKNS_4Vec2IdEEb + 152
4 QuartzCore 0x00000001038fec76 -[CALayer setPosition:] + 43
5 QuartzCore 0x00000001038ff30b -[CALayer setFrame:] + 549
6 UIKit 0x000000010452f45e -[UIView(Geometry) setFrame:] + 368
7 UIKit 0x00000001046a6a9e -[UIImageView _setViewGeometry:forMetric:] + 176
8 UIKit 0x00000001046a6db2 -[UIImageView setFrame:] + 58
9 UIKit 0x000000010457209e -[UIScrollView _layoutVerticalScrollIndicatorWithBounds:effectiveInset:contentOffset:fraction:additionalInset:cornerAdjust:showing:recalcSize:] + 2153
10 UIKit 0x00000001045714e1 -[UIScrollView _adjustScrollerIndicators:alwaysShowingThem:] + 1521
11 UIKit 0x000000010455d904 -[UIScrollView setContentOffset:] + 553
12 UIKit 0x000000010457dc00 _UIScrollViewAdjustForOverlayInsetsChangeIfNecessary + 687
13 UIKit 0x000000010457df56 -[UIScrollView(UIScrollViewInternal) setSafeAreaInsets:] + 389
14 UIKit 0x00000001045217b1 -[UIView _updateSafeAreaInsets] + 125
15 UIKit 0x000000010454f5ee -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1692
16 QuartzCore 0x000000010390549a -[CALayer layoutSublayers] + 153
17 QuartzCore 0x0000000103909589 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 401
18 QuartzCore 0x00000001038920fd _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 365
19 QuartzCore 0x00000001038bda14 _ZN2CA11Transaction6commitEv + 500
20 UIKit 0x00000001044a8c03 _afterCACommitHandler + 272
21 CoreFoundation 0x000000010708edb7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
22 CoreFoundation 0x000000010708ed0e __CFRunLoopDoObservers + 430
23 CoreFoundation 0x0000000107073324 __CFRunLoopRun + 1572
24 CoreFoundation 0x0000000107072a89 CFRunLoopRunSpecific + 409
25 GraphicsServices 0x00000001083709c6 GSEventRunModal + 62
26 UIKit 0x000000010447e23c UIApplicationMain + 159
27 App 0x000000010070dbdf main + 111
28 libdyld.dylib 0x00000001076a3d81 start + 1
29 ??? 0x0000000000000001 0x0 + 1
Thanks.
Hello adrianolucas,
You should try:
- (NSString *)cacheKey
{
if (_cacheKey) return _cacheKey;
__block NSString* s;
dispatch_block_t block = ^{
s = [NSString stringWithFormat:@"%@_%@_%.2f_%.2f_%.2f_%@_%@_%.2f_%.2f_%@",
_imageContentURL ?: [self imageHash:_originalImage],
NSStringFromCGSize(self.bounds.size),
_reflectionGap,
_reflectionScale,
_reflectionAlpha,
[self colorHash:_shadowColor],
NSStringFromCGSize(_shadowOffset),
_shadowBlur,
_cornerRadius,
@(self.contentMode)];
};
if ([NSThread currentThread].isMainThread) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}
return s;
}
For more info: https://developer.apple.com/documentation/code_diagnostics/main_thread_checker
Hi Nick,
That removed the warning as well as the trace log. Thanks a lot. The other part of the crash I mentioned in my post is due to the combination of XCode 9.0.1 with iPhone X, apparently. I'm downloading the freshly released 9.1 version today and will give a try.
Thanks again for your help.
Update:
The crash that ended up in --
App[15217:9896139] *** Terminating app due to uncaught exception 'CALayerInvalidGeometry',
reason: 'CALayer position contains NaN: [156.833 nan]'
0 CoreFoundation 0x00000001070ec1cb __exceptionPreprocess + 171
1 libobjc.A.dylib 0x0000000106600f41 objc_exception_throw + 48
2 CoreFoundation 0x0000000107160b95 +[NSException raise:format:] + 197
3 QuartzCore 0x000000010390e1bc _ZN2CA5Layer12set_positionERKNS_4Vec2IdEEb + 152
4 QuartzCore 0x00000001038fec76 -[CALayer setPosition:] + 43
5 QuartzCore 0x00000001038ff30b -[CALayer setFrame:] + 549
6 UIKit 0x000000010452f45e -[UIView(Geometry) setFrame:] + 368
7 UIKit 0x00000001046a6a9e -[UIImageView _setViewGeometry:forMetric:] + 176
8 UIKit 0x00000001046a6db2 -[UIImageView setFrame:] + 58
9 UIKit 0x000000010457209e -[UIScrollView _layoutVerticalScrollIndicatorWithBounds:effectiveInset:contentOffset:fraction:additionalInset:cornerAdjust:showing:recalcSize:] + 2153
...
...
and that occurred only with iOS 11 on iPhone X (simulator) and Xcode 9.0.1 has been fixed with Xcode 9.1