美文网首页
值得持续学习的LLDB技巧

值得持续学习的LLDB技巧

作者: 双鱼子曰1987 | 来源:发表于2021-03-09 08:27 被阅读0次

一、概述

开发调试中,常常使用LLDB加快调试,更快速简单的定位到问题点。
下面是之前收集并且整理的常用命令 、插件和 使用技巧。

二、命令

关于命令的详细用法,使用help <command> <subcommand>进行查看

2.0、关于~/.lldbinit

LLDB有了一个启动时加载的文件~/.lldbinit,每次启动都会加载。
可以添加一些自定义命令,加载插件等等。

cat ~/.lldbinit查看文件内容,包含以下信息:

  • command script import /path/to/fblldb.py
    一般系统,在~/.lldbinit默认导入facebook的fblldb.py里面命令。
    当然也可以自行安装相关插件。

  • @import 导入第三方框架,可以把基础框架放入到~/.lldbinit文件中
    例如 @import Foundation/UIKit/CoreGraphics 等系统框架,否则lldb调试相关框架会报错,

2.1、打印命令

  • p 打印基础数据类型;打印对象时会返回对象指针地址。
    p/x 变量名 打印变量的16进制(x 代表十六进制格式、t 代表二进制格式)

  • po 打印对象的desc信息

  • exp 命令作用同p命令

2.2、堆栈

  • bt 打印当前线程堆栈(backtrace的缩写)
    bt all 打印所有线程的堆栈

  • frame select 层数 跳转到某一层的堆栈
    frame variable 查看当前堆栈的变量

  • up 向上查看堆栈

  • down 向下查看堆栈

2.3、线程

  • thread list 列出所有的线程
  • thread select 线程编号 切换线程
  • thread backtrace
  • thread backtrace all 打印所有线程的堆栈
  • thread return 各种原因,不想让代码执行某个方法,或者要直接返回一个想要的值。

2.4、表达式

  • e、expr、expression 执行表达式,常用的做法是,在不重新编译的情况下,给变量赋值。
    self.view.backgroundColor = [UIColor redColor];

2.5、关于imageimage是LLDB给 target modules 取的别名 )

  • image list 列出当前执行的和依赖第三方的所有镜像

  • image lookup -n 名字 查找项目中某个变量名、函数名等,包括第三方SDK或者静态库。
    例如,用来查找同名的Category方法。

  • image lookup --address 地址+偏移量 等价于 image lookup -a 地址+偏移量
    image lookup -v -a 地址+偏移量 查找完整的源代码行信息

  • image lookup -type 类名 查看类的成员

2.6、断点

调试技巧:断点编辑,xcode中可以右键某个断点,可以进行断点编辑,可以设置某种条件下触发断点,实际开发中蛮实用。

2.6.1、breakpoint set 断点设置,其中breakpoint可以缩写为b
  • -n 方法名 根据方法名给当前类设置断点。
    也可以根据方法名给指定类多个方法设置断点,如下
    breakpoint set -n "-[ViewController save:]" -n "-[ViewController continueGame:]" -n "-[ViewController pauseGame:]"

  • breakpoint set --selector 方法名 给整个项目某个指定方法设置断点

  • -f 指定文件设定
    breakpoint set -f ViewController.m -n viewDidAppear:

  • -l 指定某一行设置断点
    breakpoint set -f ViewController.m -l 33

  • -a 给某个内存地址设置断点

  • -c 设置条件断点
    breadpoint set -n helloworld: -c flag==NO

  • -r 遍历整个项目中的所有方法,设置断点
    例如breakpoint set -r Game: 为项目所有包含 Game: 这个字符的所有方法,设置断点

2.6.2、breakpoint command 给断点设置一些命令
  • breakpoint command add 添加命令
    例如,breakpoint command add -o "po self.view" 3
    其中,-o完整写法是–one-liner,表示增加一条命令。3表示对id为3的breakpoint增加命令。

  • breakpoint command list num 查看某个断点的所有命令

  • breakpoint command delete num 删除某个断点的所有命令

2.6.3、其他
  • breakpoint list 查看断点列表
  • breakpoint disable/enable num 开启和禁止断点
  • breakpoint delete num 删除某个断点,没有入参则删除所有断点

2.7、watchpoint 内存断点

如果说breakpoint是对方法生效的断点,watchpoint就是对地址生效的断点。
想要知道某个属性什么时候被篡改了,我们该怎么办呢?就可以使用watchpoint。

2.7.1、设置
  • watchpoint set variable 设置变量
    例如,watchpoint set variable self->name
    不接受方法,因此以下命令无效watchpoint set variable self.name ,因为OC中点操作符调用setter和getter方法。

  • watchpoint set expression address 观察某个地址

2.7.2、命令
  • watchpoint command add\delete\list 同breakpoint,断点设置命令
2.7.3、其他
  • watchpoint list 查看当前所有
  • watchpoint enable/disable num 开启和禁止断点
  • watchpoint delete num

2.8、流程控制语句

  • c 继续,continue
  • n next
  • s 进入step in
  • finish 完成

2.9、targets

2.9.1、modules
  • target modules lookup 访问一个或多个目标模块的信息
    由于LLDB给target modules取了个别名image,所以这个命令我们又可以写成image lookup。 如下
    详见上面的image命令
2.9.2、stop-hook

breadpointwatchpoint 断点停止的时候,去执行一些命令。

  • target stop-hook list 查看所有的hook

  • target stop-hook add 添加的hook
    使用-o表示添加一条命令。

  • target stop-hook delete num 删除指定编号的hook,没有入参num则表达式全部

  • target stop-hook disable/enable num 开启和禁用hook,没有入参num则代表全部

2.9.3、target symbols add(add-dsym)

当我们对接framework的时候,如果只有framework代码,没有工程代码,能不能debug呢?其实我们只需要拿到工程的ipa和dSYM文件,就可以debug了,通过Attach to Process,使用命令add-dsym将dSYM文件加入target,即可只debug framework,不需要工程的代码

2.10、其他

  • call 调用方法,不打印值;p、po也有该功能,并且会打印返回值

  • disassemble,缩写为dis 打印当前目标的汇编代码

使用例子demo
1、image list
读取app的image进程内存首地址

[  0] 67EC1881-E7CC-38BC-A49E-D6FE5E755FB0 0x000000010ebe1000

2、memory read addr
addr-符号表的符号地址,可以通过mach-o查看。

1.png

addr = 第一步首地址 + mach-o的offset地址
0x10EBE9050 = 0x000000010ebe1000 + 0x00008048

2.png

3、dis -s addr
这一步的addr是上一步红框的倒叙(由于iOS是小端模式,内存地址8位倒着读)。

3.png

输出:HelloWorld/fxNSlog:,其中 fxNSlog: 是用fishhook NSLog的替换函数。

三、LLDB 和 Python

3.1、插件的原理

LLDB 有内建的,完整的 Python 支持。在LLDB中输入 script,会打开一个 Python REPL。

3.2、Chisel插件(facebook开源调试利器,原理同时)

GitHub地址

常用的命令:
  • pviews self.view 递归打印所有的view,并能标示层级

  • pvc 递归打印当前ViewController的层级

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

  • fv & fvc var
    通过类名搜索当前内存中存在的view和viewController实例的命令,支持正则搜索。

  • show/hide 无需重新编译,直接显示和隐藏view或者layer

  • caflush 重新渲染绘制界面,相当于执行了 [CATransaction flush] 方法
    注意如果在动画过程中执行这个命令,就直接渲染出动画结束的效果。
    在调试界面颜色、坐标之类的时候,可以直接在控制台修改属性,然后caflush就可以看到效果啦。

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

  • presponder self.view 打印响应者链

** 更多好用的用法,请参考help命令,值得你深入研究。 **

四、XCode调试

  • 显示汇编相关,Debug -> Debug Wokflow -> Always Show Disassembly 则会显示汇编信息。
    例子:在NSLog打断点,如下
NSString *str = @"helloworld";
id __weak objc = str;
NSLog(@"%@", objc);
image.png

参考

LLDB调试小节
objc.io#19#与调试器共舞 - LLDB 的华尔兹
iOS中教你快速掌握LLDB调试技巧
Chisel-LLDB命令插件,让调试更Easy

相关文章

  • 值得持续学习的LLDB技巧

    一、概述 开发调试中,常常使用LLDB加快调试,更快速简单的定位到问题点。下面是之前收集并且整理的常用命令 、插件...

  • lldb po 失效

    LLDB使用以及技巧

  • xcode调试技巧

    Xcode调试技巧之:LLDB Xcode调试技巧之:LLDB 1.输出视图层级关系(这是一个被隐藏的命令):po...

  • Swift 常用快捷键

    iOS开发之Xcode常用调试技巧总结 Xcode 常用快捷键 lldb技巧:

  • iOS开发调试概览

    概述 我们都知道Xcode默认的调试器是LLDB(在此之前使用的是 GDB ),但是关于LLDB的debug技巧并...

  • iOS笔记

    Xcode 1.chisel lldb技巧 github 2.Alcatraz 3.VVDocum...

  • iOS Xcode调试技巧总结

    关于调试的方法包括以下几个:日志输出&LLDB、断点、性能、一些小技巧等几个大的方面。我们一一进行学习和总结。 1...

  • LLDB调试技巧

    一、常用的命令 1.print、po输出打印 打印变量的值可以使用print(简写p)命令,该命令如果打印的是基础...

  • LLDB 调试技巧

    https://juejin.im/post/5b1cd870e51d4506dc0ac76chttps://ww...

  • LLDB调试技巧

    上学时学c++,可以感受到gdb是复杂的调试工具,难以驾驭,使用其还不如直接打Log。 虽然打log是一种方法,但...

网友评论

      本文标题:值得持续学习的LLDB技巧

      本文链接:https://www.haomeiwen.com/subject/tfeifltx.html