views:

134

answers:

2

My iPad app hangs on startup sometimes. It looks like the main thread is getting deadlocked with another thread but not sure why. Any ideas on what's causing this and how to debug this?

FYI my app starts as a splitview controller with a listview on the left and a webview on the right. If I start in portrait mode with the list view hidden the problem doesn't occur. Also, if I disable renderig of my cell when not on the main thread the app doesn't hang but the cells appear as black rectangles.

Thanks!

Here's my main thread. All of the code on this stack is Apple framework...

#0  0x971c0142 in semaphore_wait_signal_trap ()
#1  0x971c5c06 in pthread_mutex_lock ()
#2  0x02685903 in CGFontCacheLock ()
#3  0x02685869 in CGGlyphLockLockGlyphBitmaps ()
#4  0x0a90bb5b in ripc_RenderGlyphs ()
#5  0x0a9199f8 in ripc_DrawGlyphs ()
#6  0x0268464c in draw_glyphs ()
#7  0x02683e97 in CGContextShowGlyphsWithAdvances ()
#8  0x035aafba in WebCore::Font::drawGlyphs ()
#9  0x035aaaf5 in WebCore::Font::drawGlyphBuffer ()
#10 0x035aa81a in WebCore::Font::drawSimpleText ()
#11 0x035aa4c0 in drawAtPoint ()
#12 0x035a9d5c in -[NSString(WebStringDrawing) _web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:] ()
#13 0x0043f632 in -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:includeEmoji:] ()
#14 0x0043f325 in -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:] ()
#15 0x0055ba70 in -[UILabel _drawTextInRect:baselineCalculationOnly:] ()
#16 0x00559178 in -[UILabel drawTextInRect:] ()
#17 0x0045418f in -[UIView(CALayerDelegate) drawLayer:inContext:] ()
#18 0x02a708d2 in -[CALayer drawInContext:] ()
#19 0x02a704b0 in backing_callback ()
#20 0x02a6fd52 in CABackingStoreUpdate ()
#21 0x02a6f01d in -[CALayer _display] ()
#22 0x02a6eac7 in CALayerDisplayIfNeeded ()
#23 0x02a609e1 in CA::Context::commit_transaction ()
#24 0x02a60732 in CA::Transaction::commit ()
#25 0x00427556 in -[UIApplication _reportAppLaunchFinished] ()
#26 0x0042dd3e in -[UIApplication handleEvent:withNewEvent:] ()
#27 0x004294f7 in -[UIApplication sendEvent:] ()
#28 0x004311d8 in _UIApplicationHandleEvent ()
#29 0x033f817c in PurpleEventCallback ()
#30 0x02bec89c in CFRunLoopRunSpecific ()
#31 0x02beb8a8 in CFRunLoopRunInMode ()
#32 0x00427221 in -[UIApplication _run] ()
#33 0x0042f372 in UIApplicationMain ()

And another thread rendering a cell in my list view. MyFancyPantsCell & ABTableViewCellView are my classes.

#0  0x971c0142 in semaphore_wait_signal_trap ()
#1  0x971c5c06 in pthread_mutex_lock ()
#2  0x02685903 in CGFontCacheLock ()
#3  0x02685869 in CGGlyphLockLockGlyphBitmaps ()
#4  0x0a90bb5b in ripc_RenderGlyphs ()
#5  0x0a9199f8 in ripc_DrawGlyphs ()
#6  0x0268464c in draw_glyphs ()
#7  0x02683e97 in CGContextShowGlyphsWithAdvances ()
#8  0x035aafba in WebCore::Font::drawGlyphs ()
#9  0x035aaaf5 in WebCore::Font::drawGlyphBuffer ()
#10 0x035aa81a in WebCore::Font::drawSimpleText ()
#11 0x035aa4c0 in drawAtPoint ()
#12 0x035a9d5c in -[NSString(WebStringDrawing) _web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:] ()
#13 0x0043f632 in -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:includeEmoji:] ()
#14 0x0043f381 in -[NSString(UIStringDrawing) drawAtPoint:withFont:] ()
#15 0x000635ec in -[SymbolCellPainter drawContentView:selected:editing:frame:] 
#16 0x000452d0 in -[MyFancyPantsCell drawContentView:] 
#17 0x00044624 in -[ABTableViewCellView drawRect:] 
#18 0x0045418f in -[UIView(CALayerDelegate) drawLayer:inContext:] ()
#19 0x02a708d2 in -[CALayer drawInContext:] ()
#20 0x02a704b0 in backing_callback ()
#21 0x02a6fd52 in CABackingStoreUpdate ()
#22 0x02a6f01d in -[CALayer _display] ()
#23 0x02a6eac7 in CALayerDisplayIfNeeded ()
#24 0x02a609e1 in CA::Context::commit_transaction ()
#25 0x02a60732 in CA::Transaction::commit ()
#26 0x02a9e04f in CA::Transaction::release_thread ()
#27 0x971f61e3 in _pthread_tsd_cleanup ()
#28 0x971f5df6 in _pthread_exit ()
#29 0x00183bf2 in +[NSThread exit] ()
#30 0x00183b5b in __NSThread__main__ ()
#31 0x971ed81d in _pthread_start ()
#32 0x971ed6a2 in thread_start ()
+3  A: 

I looks like you've created another thread, e.g. via [object performSelectorInBackground:@selector(foo) withObject:bar]. And in that thread you call GUI methods. You should call the GUI methods with [object performSelectorOnMainThread:@selector(alpha) withObject:beta waitUntilDone:YES] (maybe create another method that just contains the GUI methods and call that one this way instead of doing 20 performSelectorOnMainThreads).

All GUI methods should run on the main thread.

DarkDust
Thanks... Now what I really want to know is how to detect when I'm doing unsafe stuff off the GUI thread. Tips for debugging. Because there aren't many clues from that stack of the "another" thread. It seems to be some Core Animation code that hooks into thread shutdown. But you can't see what code requested the view to display itself on thread shutdown.
Cal
Rule is pretty simple, I guess: only call methods on objects of type UI* in the main thread. But for debugging: tough question. I'm afraid I don't know how to find the culprit here.
DarkDust
A: 

Are you using CATransitions somewhere in your code ?

Core Animation supports two types of transactions: implicit transactions and explicit transactions. Implicit transactions are created automatically when the layer tree is modified by a thread without an active transaction and are committed automatically when the thread's run-loop next iterates. Explicit transactions occur when the the application sends the CATransaction class a begin message before modifying the layer tree, and a commit message afterwards.

It seems that implicit transactions can fire in background threads calling drawRect from there. If there's some drawing going on in the main thread at the same time - you're in trouble.

In this case, [CATransaction begin] / [CATransaction commit] MAY help.

Eugene