There are quite a few other entries on stack overflow about the:
CoreAnimation: warning, deleted thread with uncommitted CATransaction
message and to sort it by enabling CA_DEBUG_TRANSACTIONS
. In 99% of the other posts I saw, the backtrace shows the source of the uncommitted animation (see Core Animation Warning: "uncommitted CATransaction" for example, which shows functions being called in MyApp
).
In my case, I've set the CA_DEBUG_TRANSACTIONS
flag to one and I get a backtrace, but unfortunately it does not show me where it is coming from:
Deallocating
CoreAnimation: warning, deleted thread with uncommitted CATransaction; created by:
0 QuartzCore 0x00007fff95f8c76a _ZN2CA11Transaction4pushEv + 312
1 QuartzCore 0x00007fff95f8c60a _ZN2CA11Transaction15ensure_implicitEv + 276
2 QuartzCore 0x00007fff95f916f5 _ZN2CA5Layer13thread_flags_EPNS_11TransactionE + 37
3 QuartzCore 0x00007fff95f91642 _ZN2CA5Layer4markEPNS_11TransactionEjj + 64
4 QuartzCore 0x00007fff95f931df _ZN2CA5Layer25set_needs_display_in_rectERK6CGRect + 315
5 AppKit 0x00007fff97e7ebdd _NSBackingLayerSetNeedsDisplayInRect + 319
6 QuartzCore 0x00007fff95f93081 -[CALayer setNeedsDisplay] + 62
7 AppKit 0x00007fff97e7ea77 -[NSView(NSInternal) _setLayerNeedsDisplayInViewRect:] + 648
8 AppKit 0x00007fff98505049 NSViewSetNeedsDisplayInRect + 838
9 AppKit 0x00007fff97e13eed -[NSView setNeedsDisplay:] + 81
10 AppKit 0x00007fff97e2ddc0 -[_NSThemeWidget update] + 166
11 AppKit 0x00007fff980aa844 -[NSThemeFrame _updateButtonState] + 41
12 AppKit 0x00007fff98101fff -[NSWindow(NSSheets) _detachSheetWindow:] + 641
13 AppKit 0x00007fff98101a1a -[NSMoveHelper(NSSheets) _closeSheet:andMoveParent:] + 546
14 AppKit 0x00007fff9810178c -[NSWindow(NSSheets) _orderOutRelativeToWindow:] + 105
15 AppKit 0x00007fff97f232d7 -[NSWindow _reallyDoOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 2833
Unfortunately the codebase is quite large and without seeing a point of origin from my codebase I'm unsure of how to track this down.
Any suggestions?
I finally figured out a way to do this, using conditional breakpoints + symbolic breakpoints.
I would set a condition of
![[NSThread currentThread] isMainThread]
Edit: It seems like different versions of Xcode handle the condition differently. If ![[NSThread currentThread] isMainThread]
does not work (you get an error that the symbol cannot be found), try ![(NSThread*)[NSThread currentThread] isMainThread]
.
And set the symbolic breakpoint to be one of the methods shown in the backtrace. Based on the backtrace I posted earlier, the symbolic breakpoint may be '-[NSView setNeedsDisplay:]'.
Then, once '[NSView setNeedsDisplay:]' was called on a non main thread, my breakpoint was fired and I could see the state of every thread, including the backtrace to the caller. This allowed me to resolve the issue.
Also, please note that this symbolic breakpoint will extremely slow down debugging. I would not suggest leaving it running all the time.