如何找到哪个调用导致了符号断点?
How to find which call caused the symbolic breakpoint?
我设置了一个符号断点,它消失了:
线程和回溯如下。
我不明白,在 Xcode 中,如何找到符号断点关闭时实际调用的内容。甚至,如何知道它是哪个 UIView。
(我可以看到它在一个表视图中,但它可以在任意数量的表视图中的任何位置。)
这是怎么做到的?
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 [=10=]x60000, %eax ; imm = 0x60000
0x10fd4d307 <+27>: jb 0x10fd4d325 ; <+57>
0x10fd4d309 <+29>: jmp 0x10fd4d319 ; <+45>
0x10fd4d30b <+31>: movl [=10=]x60000, %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 [=10=]x8, %rsp
0x10fd4d33b <+79>: popq %rbx
0x10fd4d33c <+80>: popq %rbp
0x10fd4d33d <+81>: jmpq *0xdcd04d(%rip) ; (void *)0x000000010e558ac0: objc_msgSend
和回溯...
(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)
您需要使用右下角突出显示的按钮显示 "watch window":
。
手表 window 看起来会像
在那里你可以看到 self
。请注意,如果您在任意 asm 处放置断点,它可能不会在那里获得合理的值,因为 Obj-c 方法调用在 asm 中有点复杂。在这方面,方法条目处的符号断点通常可以正常工作。
如果你想更深入一点,你应该学习 lldb 命令界面。你可以从这个 LLDB cheat sheet and GDB and LLDB Command Examples Apple 的文档
开始
我设置了一个符号断点,它消失了:
线程和回溯如下。
我不明白,在 Xcode 中,如何找到符号断点关闭时实际调用的内容。甚至,如何知道它是哪个 UIView。
(我可以看到它在一个表视图中,但它可以在任意数量的表视图中的任何位置。)
这是怎么做到的?
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 [=10=]x60000, %eax ; imm = 0x60000
0x10fd4d307 <+27>: jb 0x10fd4d325 ; <+57>
0x10fd4d309 <+29>: jmp 0x10fd4d319 ; <+45>
0x10fd4d30b <+31>: movl [=10=]x60000, %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 [=10=]x8, %rsp
0x10fd4d33b <+79>: popq %rbx
0x10fd4d33c <+80>: popq %rbp
0x10fd4d33d <+81>: jmpq *0xdcd04d(%rip) ; (void *)0x000000010e558ac0: objc_msgSend
和回溯...
(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)
您需要使用右下角突出显示的按钮显示 "watch window":
手表 window 看起来会像
在那里你可以看到 self
。请注意,如果您在任意 asm 处放置断点,它可能不会在那里获得合理的值,因为 Obj-c 方法调用在 asm 中有点复杂。在这方面,方法条目处的符号断点通常可以正常工作。
如果你想更深入一点,你应该学习 lldb 命令界面。你可以从这个 LLDB cheat sheet and GDB and LLDB Command Examples Apple 的文档
开始