I put in a symbolic breakpoint, and it's gone off:
The thread and backtrace are below.
I don't understand, in Xcode, how to find what actually was called when the symbolic breakpoint went off. Or even, how to know which UIView it was.
(I can see that it's in a tableview, but it could be anywhere in any number of tableviews.)
How is this done?
UIKit`-[UIView(Hierarchy) layoutIfNeeded]:
-> 0x10fd4d2ec <+0>: pushq %rbp
0x10fd4d2ed <+1>: movq %rsp, %rbp
0x10fd4d2f0 <+4>: pushq %rbx
0x10fd4d2f1 <+5>: pushq %rax
0x10fd4d2f2 <+6>: movq %rdi, %rbx
0x10fd4d2f5 <+9>: leaq 0x1128470(%rip), %rax ; _UIApplicationLinkedOnVersion
0x10fd4d2fc <+16>: movl (%rax), %eax
0x10fd4d2fe <+18>: testl %eax, %eax
0x10fd4d300 <+20>: je 0x10fd4d30b ; <+31>
0x10fd4d302 <+22>: cmpl $0x60000, %eax ; imm = 0x60000
0x10fd4d307 <+27>: jb 0x10fd4d325 ; <+57>
0x10fd4d309 <+29>: jmp 0x10fd4d319 ; <+45>
0x10fd4d30b <+31>: movl $0x60000, %edi ; imm = 0x60000
0x10fd4d310 <+36>: callq 0x10fc9c15d ; _UIApplicationLinkedOnOrAfter
0x10fd4d315 <+41>: testb %al, %al
0x10fd4d317 <+43>: je 0x10fd4d325 ; <+57>
0x10fd4d319 <+45>: movq 0x1099810(%rip), %rsi ; "layoutBelowIfNeeded"
0x10fd4d320 <+52>: movq %rbx, %rdi
0x10fd4d323 <+55>: jmp 0x10fd4d337 ; <+75>
0x10fd4d325 <+57>: movq 0x10d80b4(%rip), %rax ; UIView._layer
0x10fd4d32c <+64>: movq (%rbx,%rax), %rdi
0x10fd4d330 <+68>: movq 0x1095809(%rip), %rsi ; "layoutIfNeeded"
0x10fd4d337 <+75>: addq $0x8, %rsp
0x10fd4d33b <+79>: popq %rbx
0x10fd4d33c <+80>: popq %rbp
0x10fd4d33d <+81>: jmpq *0xdcd04d(%rip) ; (void *)0x000000010e558ac0: objc_msgSend
and the backtrace...
(lldb) bt
* thread #1: tid = 0x28e3d, 0x000000010fd4d2ec UIKit`-[UIView(Hierarchy) layoutIfNeeded], queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x000000010fd4d2ec UIKit`-[UIView(Hierarchy) layoutIfNeeded]
frame #1: 0x000000010fd54239 UIKit`+[UIView(Animation) performWithoutAnimation:] + 90
frame #2: 0x000000010fe08718 UIKit`-[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 1161
frame #3: 0x000000010fe087e2 UIKit`-[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
frame #4: 0x000000010fddc2b0 UIKit`-[UITableView _updateVisibleCellsNow:isRecursive:] + 3295
frame #5: 0x000000010fe11b64 UIKit`-[UITableView _performWithCachedTraitCollection:] + 110
frame #6: 0x000000010fdf83be UIKit`-[UITableView layoutSubviews] + 222
frame #7: 0x000000010fd5fab8 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1237
frame #8: 0x000000010f6edbf8 QuartzCore`-[CALayer layoutSublayers] + 146
frame #9: 0x000000010f6e1440 QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 366
frame #10: 0x000000010f6e12be QuartzCore`CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 24
frame #11: 0x000000010f66f318 QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 280
frame #12: 0x000000010f69c3ff QuartzCore`CA::Transaction::commit() + 475
frame #13: 0x000000010f69cd6f QuartzCore`CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 113
frame #14: 0x000000010ea85267 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
frame #15: 0x000000010ea851d7 CoreFoundation`__CFRunLoopDoObservers + 391
frame #16: 0x000000010ea69f8e CoreFoundation`__CFRunLoopRun + 1198
frame #17: 0x000000010ea69884 CoreFoundation`CFRunLoopRunSpecific + 420
frame #18: 0x00000001149eda6f GraphicsServices`GSEventRunModal + 161
frame #19: 0x000000010fc9ac68 UIKit`UIApplicationMain + 159
frame #20: 0x000000010dbd0bcf DevSF`main + 111 at AppDelegate.swift:12
frame #21: 0x0000000111c8068d libdyld.dylib`start + 1
(lldb)
A solid red circle, if the debugger successfully set a breakpoint in the target process. A hollow (white filled) circle, either the breakpoint is disabled or warning occurred when trying to set the breakpoint. To determine the difference, hover over the breakpoint and see if there's a warning.
To modify a single breakpoint, hover over the breakpoint icon in the editor and select the settings (gear) icon. A peek window is added to the editor. At the top of the peek window, there's a hyperlink that indicates the location of the breakpoint.
Breakpoint Warnings. When debugging, a breakpoint has two possible visual states: a solid red circle and a hollow (white filled) circle. If the debugger is able to successfully set a breakpoint in the target process, it will stay a solid red circle.
If a source file has changed and the source no longer matches the code you're debugging, the debugger won't set breakpoints in the code by default. Normally, this problem happens when a source file is changed, but the source code wasn't rebuilt. To fix this issue, rebuild the project.
You need to show the "watch window" using the highlighted button in the bottom right corner:
.
The watch window will look somtehing like
and there you can see self
. Note that if you put breakpoint at arbitrary asm, it might not get reasonable values there because Obj-c method call is a bit complicated in asm. Symbolic breakpoints at methods entries typically work OK in this respect.
If you want to go one level deeper you should learn lldb command interface. You may start at this LLDB cheat sheet and GDB and LLDB Command Examples Apple's doc
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