In my app I have a homegrown version of UICollectionView (I wrote it before UICollectionView existed, and it seems to be more performant than UICollectionView for my use case). It consists of several tiles in a scrollview.
To aid in scrolling performance, and because each tile consists of around a dozen PNGs on top of each other, each tile is pre-rendered to an NSCache using NSOperations and an NSOperationQueue. Without this optimisation, scrolling performance is terrible.
As well as several PNGs, each tile has (or may have) a couple of pieces of text.
Each NSOperation, to avoid causing problems doing any kind of rendering on a background thread (which of course, is a UIKit no-no), uses CoreGraphics and NSAttributedStrings to render the image.
This brings me to the crash. The crash (below) seems to relate to NSAttributedString rendering. As this NSOperationQueue full of tile render operations is the only place in my app that uses NSAttributedStrings, and gets called a lot, I have to assume it's the culprit. We see the crash occurring reasonably often in our crash reporting, but not often enough that we have a hope of reliably reproducing it in-house (our app has a pretty massive userbase).
Fascinatingly, the crash only occurs on iOS 7. Anyone have any ideas? Here's an example of a crash:
Incident Identifier: 3BE1FF37-4288-40A9-954D-1AD909987D05
CrashReporter Key: 000339CB-9B5B-46EE-B256-4D911B190E7D
Hardware Model: iPhone5,2
Process: AppName [733]
Path: /Users/USER/AppName.app/AppName
Identifier: com.companyname.appname
Version: 2.0.1
Code Type: ARM
Parent Process: launchd [1]
Date/Time: 2013-10-03 23:32:20 +0000
OS Version: iPhone OS 7.0.2 (11A501)
Report Version: 104
Exception Type: SIGBUS
Exception Codes: BUS_ADRALN at 0x100078c
Crashed Thread: 0
Thread 0 Crashed:
0 ??? 0x0100078c 0x0 + 0
1 UIFoundation 0x36fbf027 -[NSLayoutManager _drawLineForGlyphRange:type:baselineOffset:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:isStrikethrough:] + 3358
2 UIFoundation 0x36ffdd1f -[NSLayoutManager drawUnderlineForGlyphRange:underlineType:baselineOffset:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:] + 86
3 UIFoundation 0x36fc024d -[NSLayoutManager _lineGlyphRange:type:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:isStrikethrough:] + 1184
4 UIFoundation 0x36ffde2f -[NSLayoutManager underlineGlyphRange:underlineType:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:] + 78
5 UIFoundation 0x36fd43bf -[NSLayoutManager _drawGlyphsForGlyphRange:atPoint:] + 5734
6 UIFoundation 0x36ffdbf7 -[NSLayoutManager drawGlyphsForGlyphRange:atPoint:] + 38
7 UIFoundation 0x37013f01 -[NSStringDrawingTextStorage drawTextContainer:withRect:graphicsContext:baselineMode:scrollable:padding:] + 968
8 UIFoundation 0x3700e5bd __NSStringDrawingEngine + 10293
9 UIFoundation 0x3701172d -[NSAttributedString(NSExtendedStringDrawing) drawWithRect:options:context:] + 525
10 UIKit 0x31ed9f5d -[UILabel _drawTextInRect:baselineCalculationOnly:] + 3436
11 UIKit 0x31f419e7 -[UILabel drawTextInRect:] + 558
12 UIKit 0x31f417af -[UILabel drawRect:] + 78
13 UIKit 0x31f41749 -[UIView drawLayer:inContext:] + 372
14 QuartzCore 0x31b78049 -[CALayer drawInContext:] + 100
15 QuartzCore 0x31b61813 CABackingStoreUpdate_ + 1859
16 QuartzCore 0x31c3b735 ___ZN2CA5Layer8display_Ev_block_invoke + 53
17 QuartzCore 0x31b610c3 x_blame_allocations + 83
18 QuartzCore 0x31b60d77 CA::Layer::display_() + 1119
19 QuartzCore 0x31b44969 CA::Layer::display_if_needed(CA::Transaction*) + 209
20 QuartzCore 0x31b44601 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 25
21 QuartzCore 0x31b4400d CA::Context::commit_transaction(CA::Transaction*) + 229
22 QuartzCore 0x31b43e1f CA::Transaction::commit() + 315
23 QuartzCore 0x31b3db4d CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 57
24 CoreFoundation 0x2f706f71 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 21
25 CoreFoundation 0x2f7048ff __CFRunLoopDoObservers + 287
26 CoreFoundation 0x2f704c4b __CFRunLoopRun + 739
27 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
28 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
29 GraphicsServices 0x343a62eb GSEventRunModal + 138
30 UIKit 0x31f261e5 UIApplicationMain + 1136
31 My App 0x0002cc37 main (main.m:18)
32 libdyld.dylib 0x39f2fab7 start + 3
Thread 1:
0 libsystem_kernel.dylib 0x39fd3838 kevent64 + 24
1 libdispatch.dylib 0x39f1c643 _dispatch_mgr_thread + 39
Thread 2:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 Foundation 0x3005d827 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 255
6 Foundation 0x300ae669 -[NSRunLoop(NSRunLoop) run] + 81
7 My App 0x0003900f -[EndpointOperation start] (EndpointOperation.m:268)
8 Foundation 0x3010eafd __NSOQSchedule_f + 61
9 libdispatch.dylib 0x39f1f4bf _dispatch_async_redirect_invoke + 111
10 libdispatch.dylib 0x39f207e5 _dispatch_root_queue_drain + 225
11 libdispatch.dylib 0x39f209d1 _dispatch_worker_thread2 + 57
12 libsystem_pthread.dylib 0x3a04adff _pthread_wqthread + 298
13 libsystem_pthread.dylib 0x3a04acc4 start_wqthread + 8
Thread 3:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 Foundation 0x300aa651 +[NSURLConnection _resourceLoadLoop:] + 320
6 Foundation 0x3011fdc7 __NSThread__main__ + 1063
7 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
8 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
9 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 4:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 Foundation 0x3005d827 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 255
6 My App 0x000a1287 +[XMPPStream xmppThreadMain] (XMPPStream.m:4463)
7 Foundation 0x3011fdc7 __NSThread__main__ + 1063
8 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
9 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
10 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 5:
0 libsystem_kernel.dylib 0x39fe6440 __select + 20
1 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
2 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
3 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 6:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 WebCore 0x375d27dd RunWebThread(void*) + 421
6 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
7 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
8 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 7:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 libAVFAudio.dylib 0x2e64d5b3 GenericRunLoopThread::Entry(void*) + 131
6 libAVFAudio.dylib 0x2e641bf7 CAPThread::Entry(CAPThread*) + 179
7 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
8 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
9 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 8:
0 libsystem_kernel.dylib 0x39fe5f38 __psynch_cvwait + 24
1 libsystem_pthread.dylib 0x3a04d041 pthread_cond_wait + 40
2 JavaScriptCore 0x3069340d JSC::BlockAllocator::blockFreeingThreadMain() + 209
3 JavaScriptCore 0x30690a73 WTF::wtfThreadEntryPoint(void*) + 15
4 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
5 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
6 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 9:
0 libsystem_kernel.dylib 0x39fe5f38 __psynch_cvwait + 24
1 libsystem_pthread.dylib 0x3a04d041 pthread_cond_wait + 40
2 JavaScriptCore 0x30831af7 JSC::GCThread::waitForNextPhase() + 79
3 JavaScriptCore 0x30831b51 JSC::GCThread::gcThreadMain() + 53
4 JavaScriptCore 0x30690a73 WTF::wtfThreadEntryPoint(void*) + 15
5 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
6 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
7 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 10:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 Foundation 0x3005d827 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 255
6 Foundation 0x300ae669 -[NSRunLoop(NSRunLoop) run] + 81
7 My App 0x000b1635 +[GCDAsyncSocket cfstreamThread] (GCDAsyncSocket.m:6714)
8 Foundation 0x3011fdc7 __NSThread__main__ + 1063
9 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
10 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
11 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 11:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f6b31ab CFRunLoopRun + 98
5 CoreMotion 0x2fd27399 CLSF_thorntonUpdate_6x6 + 57225
6 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
7 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
8 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 12:
0 libsystem_kernel.dylib 0x39fd3ad4 semaphore_wait_trap + 8
1 MediaToolbox 0x30b60d0f fpa_AsyncMovieControlThread + 1755
2 CoreMedia 0x2fc9b23f figThreadMain + 195
3 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
4 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
5 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 13:
0 libsystem_kernel.dylib 0x39fe6c7c __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x3a04acc4 start_wqthread + 8
Thread 14:
0 libsystem_kernel.dylib 0x39fe6c7c __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x3a04acc4 start_wqthread + 8
Thread 15:
0 libsystem_kernel.dylib 0x39fe6c7c __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x3a04acc4 start_wqthread + 8
Thread 16:
0 libsystem_kernel.dylib 0x39fe6c7c __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x3a04acc4 start_wqthread + 8
Thread 0 crashed with ARM Thread State:
pc: 0x0100078c r7: 0x27ddb5e8 sp: 0x27ddb5b8 r0: 0x16d20b30
r1: 0x27ddb5b8 r2: 0x0100078c r3: 0x00000000 r4: 0x169a6d78
r5: 0x16b33250 r6: 0x2fe140a5 r8: 0x27ddb5b8 r9: 0x164ea8b8
r10: 0x157ea030 r11: 0x00000004 ip: 0x3a265964 lr: 0x2fe1402d
cpsr: 0x40000010
Here's the code:
NSMutableDictionary *attributes = [@{NSFontAttributeName: [[self class] unreadChatLabelFont]
, NSForegroundColorAttributeName: [UIColor whiteColor]} mutableCopy];
if ([self unreadChatLabelHasDropShadow]) {
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowOffset = CGSizeMake(0, -1);
shadow.shadowColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: .5];
attributes[NSShadowAttributeName] = shadow;
}
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString: unreadChats
attributes: attributes];
[attributedString drawAtPoint: labelPosition];
And in a different place in the same class:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShadowWithColor(context, CGSizeMake(0,1), 1.5, [UIColor blackColor].CGColor);
NSDictionary *attributes = @{NSFontAttributeName: [[self class] displayNameFont], NSForegroundColorAttributeName: [UIColor whiteColor]};
NSAttributedString *displayName = [[NSAttributedString alloc] initWithString: dictionary[kDisplayNameKey]
attributes: attributes];
[displayName drawAtPoint: [[self class] displayNamePosition]];
// Remove shadow from draw settings
CGContextSetShadowWithColor(context, CGSizeMake(0,1), 1.5, NULL);
Ensure that you are not adding a label, changing text in the label or drawing text on a thread other than the main thread. Whilst the documentation does say the following:
NSTextStorage, NSLayoutManager, and NSTextContainer can be accessed from subthreads as long as the app guarantees the access from a single thread.
I have found in the past that they are not entirely thread safe and some glyph related operations must occur on the main thread and will produce an exception or crash with an EXC_BAD_ACCESS
if they are not. Whilst this is not exactly like your crash report, this is a possible cause of the crash.
To rule out cross thread UIKit drawing as an issue, dispatch your call to -drawAtPoint:
onto the main queue.
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:unreadChats attributes:attributes];
dispatch_async(dispatch_get_main_queue(), ^{
[attributedString drawAtPoint: labelPosition];
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With