Search code examples
macoscocoaappkitquartz-core

deleted thread with uncommitted CATransaction not showing source?


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?


Solution

  • 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.