LLDB调试及插件

LLDB是我们开发中都会使用到的调试工具,我们今天来总结一下常见的用法以及一些好用的LLDB插件。

LLDB

断点

断点是LLDB中最常用的功能了,平时都是在代码中手动设置断点,今天通过LLDB来添加断点。

当程序在运行过程中,我们可以点击暂停或者view debug是程序进入到LLDB状态,这时我们就可以进行LLDB调试。
image.png

添加断点

br set -n test1        //给函数添加断点, br是breakpoint的简写

br set -n '-[ViewController test:]'   //OC方法添加断点

br set -r swwtest     //整个项目中,方法名字包含swwtest的都添加断点

br set --selector test:    //整个项目中,test:的方法添加断点,无论对象方法还是类方法

br set --file ViewController.m --selector test:   //在某个文件中添加断点
复制代码

查看所有断点

br list
复制代码

禁用/启用断点

br disable 1    //可以禁用一组,也可以某一个,比如,1.2
br enable 1     //启用
复制代码

删除断点

br delete 1    //只能删除1组断点,不能删除某一个
复制代码

image.png

代码执行

expression或者它的简写p是执行后面代码的指令。在调试的过程中,我们可以用来修改某个值,使程序进入不同的流程。

流程控制

$continue/c 继续

$next/n   单步执行

$s       单步执行,遇到子函数会进去

复制代码
$thread return   本函数中不往下执行,直接返回
复制代码

thread return可以用来绕过函数执行,例如在- (void)test中加上断点,使用thread return可以不执行里面代码,继续向下执行。

查看堆栈

$bt  查看堆栈信息

$frame variable    查看参数

$up         切换当前frame, 向上
$down       向下
复制代码

内存断点

br -a 0x123456     设置内存断点,这个地址如果是方法,那么进入方法的时候就会进入断点
复制代码

有时候我们需要监听某个值的变化,可以使用内存断点,原理类似于OC的KVO。当值发生变化时,就会触发断点,并且可以查看新值和旧值。

$watchpoint set variable p1->_name      给p1对象的name属性添加断点。
复制代码
$watchpoint set expression 0x0000000283b81bd0      给这块内存添加断点,监听内存中值当变化。
复制代码

image.png

stop-hook

给整个程序下一个断点指令,当程序被断住时,会触发我们下的命令。

target stop-hook add -o "frame variable"    当程序进入断点时,就会执行frame variable指令
复制代码
target stop-hook list        查看所有stop-hook
target stop-hook delete 1    删除1组
复制代码

.lldbinit

在用户文件夹下cd ~,有一个.lldbinit的隐藏文件(没有就创建一个),这个文件是每次lldb启动时,都会加载这个文件,我们可以在这个文件中添加指令,一劳永逸。

image.png

image.png

chisel

chisel是facebook开发的lldb插件,地址是chisel,今天我们看看常用的方法。

pvc  打印所有控制器

pviews 打印所有view
pviews 0x1234321   打印这个view的子view

pclass 0x100b06370  打印这个类的继承链

pmethods 0x100b06370  打印这个类包含的方法
复制代码

简单的写了一个页面,使用chisel来找到页面中的控价

IMG_0004.PNG

(lldb) pviews
<UIWindow: 0x100b0cf20; frame = (0 0; 375 667); autoresize = W+H; gestureRecognizers = <NSArray: 0x2823ae130>; layer = <UIWindowLayer: 0x282dd13c0>>
   | <UIView: 0x100b13920; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x282dd29a0>>
   |    | <UIButton: 0x100b0dbb0; frame = (87.5 169; 200 60); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x282dd1a40>>
   |    |    | <UIButtonLabel: 0x100a14df0; frame = (73 19.5; 54 21.5); text = 'Button'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280ed4690>>
   |    | <UIButton: 0x100b115c0; frame = (87.5 249; 200 60); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x282dd22e0>>
   |    |    | <UIButtonLabel: 0x100a14af0; frame = (73 19.5; 54 21.5); text = 'Button'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280ed9900>>
   |    | <UITextField: 0x101830200; frame = (87.5 328.5; 200 30); text = ''; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x2823aebe0>; layer = <CALayer: 0x282dd2440>>
   |    |    | <_UITextFieldRoundedRectBackgroundViewNeue: 0x100b12db0; frame = (0 0; 200 30); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x282dd26e0>>
   |    |    | <_UITextFieldContentView: 0x100b12690; frame = (7 2; 186 26); opaque = NO; userInteractionEnabled = NO; layer = <__UITextTiledLayer: 0x2809c5c80>>
   |    |    |    | <__UITileLayer: 0x282385d70> (layer)
(lldb) pviews 0x100b13920
<UIView: 0x100b13920; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x282dd29a0>>
   | <UIButton: 0x100b0dbb0; frame = (87.5 169; 200 60); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x282dd1a40>>
   |    | <UIButtonLabel: 0x100a14df0; frame = (73 19.5; 54 21.5); text = 'Button'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280ed4690>>
   | <UIButton: 0x100b115c0; frame = (87.5 249; 200 60); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x282dd22e0>>
   |    | <UIButtonLabel: 0x100a14af0; frame = (73 19.5; 54 21.5); text = 'Button'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x280ed9900>>
   | <UITextField: 0x101830200; frame = (87.5 328.5; 200 30); text = ''; opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x2823aebe0>; layer = <CALayer: 0x282dd2440>>
   |    | <_UITextFieldRoundedRectBackgroundViewNeue: 0x100b12db0; frame = (0 0; 200 30); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x282dd26e0>>
   |    | <_UITextFieldContentView: 0x100b12690; frame = (7 2; 186 26); opaque = NO; userInteractionEnabled = NO; layer = <__UITextTiledLayer: 0x2809c5c80>>
   |    |    | <__UITileLayer: 0x282385d70> (layer)
(lldb) pvc
<ViewController 0x100b06370>, state: appeared, view: <UIView 0x100b13920>
(lldb) pclass 0x100b06370
ViewController
   | UIViewController
   |    | UIResponder
   |    |    | NSObject
(lldb) pmethods 0x100b06370
Class Methods:
+ (void)load

Instance Methods:
- (id)btn1
- (id)btn2
- (id)tf
- (void)btn2Click:(id)arg0 
- (id)matchString:(id)arg0 toRegexString:(id)arg1 
- (void)swwTest1
- (void)swwTest2
- (void)swwTest3
- (void)swwTest4
- (void)setBtn1:(id)arg0 
- (void)setBtn2:(id)arg0 
- (void)setTf:(id)arg0 
- (void)setT:(id)arg0 
- (id)t
- (void).cxx_destruct
- (void)touchesBegan:(id)arg0 withEvent:(id)arg1 
- (void)viewDidLoad
- (id)manager
- (void)setManager:(id)arg0 
(lldb) pinternals 0x100b06370
(ViewController) $24 = {
  UIViewController = {
    UIResponder = {
      NSObject = {
        isa = ViewController
      }
    }
  }
  _btn1 = 0x0000000100b0dbb0
  _btn2 = 0x0000000100b115c0
  _tf = 0x0000000101830200
  _t = nil
  _manager = nil
}
(lldb) 
复制代码

找到所属的控制器和控件

fvc -v 0x0000000100b0dbb0    找到一个空间所属控制器

fv UIButton    通过类名找控件
复制代码

image.png
找到对应的控件

flicker 0x139e0aca0    使这个控件闪烁一下
vs 0x139e0aca0      定位到这个控件,并可以调试其关联的控件
复制代码

image.png

DSLLDB

DSLLDB下载到本地,我把文件放在了/opt文件夹下了,然后配置.lldbinit文件command script import /opt/LLDB/lldb_commands/dslldb.py当app被脱去符号,只用bt不能看到方法名字了,DSLLDB可以使用sbt,把脱去的符号恢复

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享