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:打印视图层级结构。


目录
相关文章
|
5月前
VSCode调试 添加命令行参数
VSCode调试 添加命令行参数
240 0
|
监控 NoSQL
JLink + GDB 调试方法
本节主要介绍嵌入式开发中常用的JLink+GDB调试方法。 调试所需软件 J-link,可以从https://www.segger.com下载对应操作系统的软件包,然后安装(注意:segger是仿真器的名字,相当常用的一款,仿真器的接口也是固定的,一般开发版上都会带有这个调试接口,如图) 运行JLinkGDBServer 按照上图中的配置,配置GDBServer,然后点击OK,进入下一个界面 注意,如果硬件连接没有问题,那么上图中的J-Link和 Device栏中显示绿色,GDB显示为红色,因为我们还没有运行GDB软件。
6727 46
|
3月前
|
NoSQL Linux Android开发
OPENJTAG调试学习(三):使用 gdb 命令行进行调试
OPENJTAG调试学习(三):使用 gdb 命令行进行调试
48 0
|
iOS开发
LLDB 调试命令、插件和技巧(上)
LLDB 调试命令、插件和技巧(上)
514 0
|
10月前
|
运维 监控 数据可视化
JVM调试命令与调试工具
JVM调试命令与调试工具
177 0
|
10月前
|
NoSQL Linux 网络安全
【Linux C】GCC编译 && GDB调试 从入门到放弃 (gcc调试选项详解、gdb调试、条件断点、远程调试、脚本化调试)(二)
阅读本文可能需要一些基础,比如:C语言基础、Linux基础操作、vim、防火墙等。篇幅有限,本文讲的“比较浅显”。 通过本文你将学会: gcc编译 gdb调试
|
10月前
|
NoSQL IDE Linux
【Linux C】GCC编译 && GDB调试 从入门到放弃 (gcc调试选项详解、gdb调试、条件断点、远程调试、脚本化调试)(一)
阅读本文可能需要一些基础,比如:C语言基础、Linux基础操作、vim、防火墙等。篇幅有限,本文讲的“比较浅显”。 通过本文你将学会: gcc编译 gdb调试
|
iOS开发
LLDB 调试命令、插件和技巧(中)
LLDB 调试命令、插件和技巧(中)
389 0
|
缓存 JavaScript 前端开发
|
iOS开发
LLDB调试iOS应用程序
如何利用LLDB调试iOS应用程序?本文为您揭晓。
402 1
LLDB调试iOS应用程序