LLDB 调试命令、插件和技巧(下)

简介: LLDB 调试命令、插件和技巧(下)
brew update
brew install chisel

安装完成按照安装日志上的提示,在 ~/.lldbinit 文件中添加一行,没有则新建。 提示类似如下:


==> Caveats
Add the following line to ~/.lldbinit to load chisel when Xcode launches:
  command script import /usr/local/opt/chisel/libexec/fblldb.py

做好上面的步骤,然后重启 Xcode 就可以尝试下了。


LLDB

与 chisel 都是用 Python 写的,其安装需要手动下载仓库,然后将仓库中 dslldb.py 文件的路径用与上述同样的方式添加到 .lldbinit 中。


扩展


pviews

打印当前层级结构。

(lldb) pviews view
<TestView: 0x18df8070; baseClass = UIControl; frame = (144 9; 126 167); layer = <CALayer: 0x18df8150>>
   | <UIView: 0x18df81d0; frame = (0 0; 126 126); userInteractionEnabled = NO; layer = <CALayer: 0x18df8240>>
   | <UIImageView: 0x18df8330; frame = (0 0; 126 126); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x18df83b0>>
   | <UILabel: 0x18df8460; frame = (0 135; 126 14); text = 'haha'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x18df7fb0>>
   |    | <_UILabelContentLayer: 0x131a3d50> (layer)
   | <UILabel: 0x18df8670; frame = (0 155; 126 12); text = 'hahaha'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x18df8730>>
   |    | <_UILabelContentLayer: 0x131bea10> (layer)
   | <UIImageView: 0x18df88d0; frame = (0 9; 28 27); hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x18df8ba0>>


pvc

递归打印 viewController 层级,利用它我们可以对 viewController 的结构一目了然。

(lldb) pvc
<TabBarController: 0x13772fd0; view = <UILayoutContainerView; 0x151b3a30>; frame = (0, 0; 414, 736)>
   | <UINavigationController: 0x1602b800; view = <UILayoutContainerView; 0x1b00aca0>; frame = (0, 0; 414, 736)>
   |   | <FirstViewController: 0x16029c00; view = <UIView; 0x1b01e1c0>; frame = (0, 0; 414, 736)>
   | <UINavigationController: 0x138c5200; view = <UILayoutContainerView; 0x1316a080>; frame = (0, 0; 414, 736)>
   |   | <SecondViewController: 0x16030400; view = <UIView; 0x2094b370>; frame = (0, 0; 414, 736)>
   |   |   | <SecondChildViewController: 0x15af6000; view = <UIView; 0x18d4e650>; frame = (0, 64; 414, 628)>
   | <UINavigationController: 0x1383ca00; view = <UILayoutContainerView; 0x13180070>; frame = (0, 0; 414, 736)>
   |   | <ThirdViewController: 0x138ddc00; view = <UIView; 0x18df6650>; frame = (0, 0; 414, 736)>
   |   |   | <ThirdChild1ViewController: 0x1393fe00; view = <UIView; 0x131ec000>; frame = (0, 0; 414, 672)>
   |   |   | <ThirdChild2ViewController: 0x138dce00; view = <UIView; 0x204075a0>; frame = (414, 0; 414, 672)>
   |   |   | <ThirdChild3ViewController: 0x138a8e00; view = <UIView; 0x20426250>; frame = (828, 0; 414, 672)>
   | <UINavigationController: 0x160eca00; view = <UILayoutContainerView; 0x152f7d90>; frame = (0, 0; 414, 736)>
   |   | <FourViewController: 0x13157cc0; view not loaded>


visualize

使用 Mac 的预览打开一个 UIImage,CGImageRef,UIView 或 CALayer。

(lldb) visualize imageView


fv & fvc

fvfvc 这两个命令是用来通过类名搜索当前内存中存在的 view 和 viewController 实例的命令,支持正则搜索。

(lldb) fv scrollView
0x18d3b8c0 UIScrollView
0x137d0c50 UIScrollView
0x131b1580 UIScrollView
0x131b2070 UIScrollView
(lldb) fvc Home
0x1393fe00 HomeFeedsViewController
0x138a8e00 HomeFeedsViewController
(lldb)


show & hide

这两个命令用来显示和隐藏一个指定的 UIView。


mask/umask border/unborder


这两组命令用来标识一个 view 或 layer 的位置时用,mask 用来在 view 上覆盖一个半透明的矩形,border 可以给 view 添加边框。


caflush

这个命令会重新渲染,即可以重新绘制界面,相当于执行了 [CATransaction flush] 方法,要注意如果在动画过程中执行这个命令,就直接渲染出动画结束的效果。


当你想在调试界面颜色、坐标之类的时候,可以直接在控制台修改属性,然后 caflush 就可以看到效果啦,是不是要比改代码,然后重新 build 省事多了呢。


(lldb) p view
(long) $122 = 140718754142192
(lldb) e (void)[$122 setBackgroundColor:[UIColor greenColor]]
(lldb) caflush


自定义插件

比如设计一个打印 keyWindow 的 windowLevel 的命令:

创建 python 脚本文件 /magical/commands/example.py :


#!/usr/bin/python
# Example file with custom commands, located at /magical/commands/example.py
import lldb
import fblldbbase as fb
def lldbcommands():
  return [ PrintKeyWindowLevel() ]
class PrintKeyWindowLevel(fb.FBCommand):
  def name(self):
    return 'pkeywinlevel'
  def description(self):
    return 'An incredibly contrived command that prints the window level of the key window.'
  def run(self, arguments, options):
    # It's a good habit to explicitly cast the type of all return
    # values and arguments. LLDB can't always find them on its own.
    lldb.debugger.HandleCommand('p (CGFloat)[(id)[(id)[UIApplication sharedApplication] keyWindow] windowLevel]')


其中定义了 PrintKeyWindowLevel 的类,需要实现 namedescriptionrun 方法来分别告诉名称、描述、和执行实体。


创建好脚本后,然后在前面安装时创建的 ~/.lldbinit 文件中添加一行:


script fblldb.loadCommandsInDirectory('/magical/commands/')

然后重启 Xcode 之后就可以使用自定义的命令啦。


技巧



taplog + flicker + show/hide

  1. taplog 点击控件,打印控件地址、大小和透明度等。
  2. flicker 执行 地址 命令,控件会闪烁。
  3. show/hide 执行 地址 命令,控制显示或隐藏。


vs 动态调试

执行 vs 后进入动态调试阶段,会出现五个命令。

(lldb) vs 0x728123771817
Use the following and (q) to quit.
  • w:移动到父视图。
  • s:移动到第一个子视图。
  • a:移动到上一个兄弟视图。
  • d:移动到下一个兄弟视图。
  • p:打印视图层级结构。


目录
相关文章
|
算法 编译器 程序员
【C/C++ 解惑 】 std::move 将左值转换为右值的背后发生了什么?
【C/C++ 解惑 】 std::move 将左值转换为右值的背后发生了什么?
507 0
|
搜索推荐 JavaScript 前端开发
Gmail邮箱API发送邮件的方法有什么
使用Gmail API发送邮件,需先获取API访问权限,包括在Google Cloud Platform上创建项目,启用Gmail API,生成API密钥或OAuth 2.0凭据。然后,用Python等编程语言设置API请求,指定邮件详情。发送简单邮件涉及创建Base64编码的消息体,而带附件的邮件需编码为multipart格式。可添加邮件头信息,并处理发送结果以确保成功。Gmail API使应用能集成自动化、个性化的邮件发送功能,提升效率和体验。
|
云安全 安全 网络安全
网络安全 | 什么是云安全?
云安全是应对企业外部和内部威胁的关键,它集合了多种程序和技術,确保云服务(如IaaS、PaaS、SaaS)的安全运行。云计算让企业能灵活扩展,但也带来数据安全管理挑战,包括可见性不足、多租户风险、访问控制困难和合规性问题。配置错误也是主要威胁。应对策略包括身份和访问管理(IAM)、数据丢失预防(DLP)、信息安全和事件管理(SIEM)以及业务连续性和灾难恢复计划。企业需构建安全的云计算框架,遵循网络安全框架,并利用云安全态势管理(CSPM)来防止错误配置造成的风险。
608 0
|
编译器 测试技术 开发工具
让你的 XCode 编译链接耗时减半
让你的 XCode 编译链接耗时减半
2048 0
让你的 XCode 编译链接耗时减半
|
9月前
|
Linux API iOS开发
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
697 14
Binary Ninja 4.2.6455 (macOS, Linux, Windows) - 反编译器、反汇编器、调试器和二进制分析平台
|
IDE 开发工具 虚拟化
EFI VMware Virtual SCSI Hard Drive (0.0) ... No Media
EFI VMware Virtual SCSI Hard Drive (0.0) ... No Media
|
Linux Swift iOS开发
LLDB:强大的源代码级调试工具
LLDB:强大的源代码级调试工具
1583 0
|
存储 前端开发 JavaScript
异步Promise及Async/Await 异步之神详解
异步Promise及Async/Await 异步之神详解
480 1
|
前端开发 rax 网络协议
x64汇编语言与逆向工程基础指南(一)
x64汇编语言与逆向工程基础指南(一)
2714 0
|
IDE 开发工具 Swift
【Swift开发专栏】Swift的Xcode调试技巧
【4月更文挑战第30天】本文介绍了Swift开发者必备的Xcode调试技巧,分为三部分:调试界面概览、常用操作和高级技术。内容涵盖调试区域、断点管理、单步调试、变量查看及LLDB命令行调试。通过学习条件断点、异常断点、视图调试等高级技术,开发者能提升问题解决效率。熟悉这些工具将有助于优化开发流程并增强项目性能。
616 1