LLDB调试之Chisel

1,843 阅读7分钟

0、Chisel安装

brew update
brew install chisel

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

command script import /usr/local/opt/chisel/libexec/fblldb.py

一、Autolayout

autolayout中有一种bug叫Ambiguous Layouts,意思是你设置的约束不足以确定view的位置或大小。比如你只设置了X轴的位置,没有设置Y轴的位置

autolayout提供了专门判断和查找这类问题的方法

hasAmbiguousLayout用于判断是否存在Ambiguous Layouts.
_autolayoutTrace用于查找存在的Ambiguous Layouts.

1、alamborder

作用

给约束有问题的view添加边框

语法

alamborder [--color=color] [--width=width];

  • --color/-c: border的颜色,参数为string类型,比如’red’, ‘green’, ‘magenta’等,不设置默认为红色。
  • --width/-w: border的宽度,参数为CGFloat类型,不设置默认宽度为2。

2、alamunborder

作用

将alamborder设置的border去掉.

3、paltrace

作用

打印某个View的autolayout详细信息,相当于调用**_autolayoutTrace**;

语法

paltrace viewAddress

二、Print

1、pviews

作用

循环打印view层级,正常情况下等效于调用recursiveDescription语法

语法

pviews [--up] [--depth=depth] viewAddress

  • --up/-u 以view为起点向上打印,直到window层
  • --depth/-d 传入int类型,表示打印层数,0表示没有限制

2、pvc

作用

循环打印viewController的层级

语法

pvc aViewControllerAddress 不传参数默认viewController为当前的VC

3、pclass

作用

循环打印class的继承关系

语法

pclass objectAddress

4、presponder

作用

打印响应链

语法

presponder startResponder

startResponder 是UIResponder对象,响应链开始位置

5、ptv

作用

打印屏幕中显示的tableView,主要是与pcells联合使用。如果有多个tableView,打印View层级中最上面的一个

语法

ptv

看看当前最上面是哪个tableView

6、pcells

作用

打印tableView中当前可见的cell,如果有多个tableView,打印View层级中最上面的tableView的可见cell

语法

pcells

7、pinternals

作用

打印一个对象内部的成员变量,这个方法我一般用来看model属性

语法

pinternals objectAddress

8、pdata

作用

对编码过的NSData进行解码打印,等效于调用-[NSString initWithData:encoding:]

语法

pdata [--encoding=encoding] data

  • data: 需要打印的data,NSData类型
  • --encoding/-e: 编码类型,如果缺省默认为utf8,主要支持的类型有
      • ascii,
      • utf8,
      • utf16, unicode,
      • utf16l (Little endian),
      • utf16b (Big endian),
      • utf32,
      • utf32l (Little endian),
      • utf32b (Big endian),
      • latin1, iso88591 (88591),
      • latin2, iso88592 (88592),
      • cp1251 (1251),
      • cp1252 (1252),
      • cp1253 (1253),
      • cp1254 (1254),
      • cp1250 (1250),

9、pkp

作用

通过-valueForKeyPath:打印key path对应的值。

语法

pkp keypath

  • 以前打印属性一般都用po obj.xxx,现在我想用pkp obj.xxx是一个更好的选择了,因为po obj.xxx是调用getter方法,如果没有getter方法就无法打印了。pkp obj.xxx不仅会调用getter方法,没有getter方法还会去查找成员变量

10、pivar

作用

打印对象成员变量

语法

pivar object ivarName

  • object: id类型,要打印成员变量的对象
  • ivarName: 成员变量的名称,注意:如果是属性,对应成员变量的名字默认有_前缀
说明

这个方法有点鸡肋,pinternals一下子可以打印出所有的成员变量,用起来更方便,如果你只想打印某一个成员变量,用pkp应该更爽

11、pca

作用

从渲染服务器的角度来打印layer tree,语法的完整名字是PrintCoreAnimationTree,相当于调用po [NSString stringWithCString:(char *)CARenderServerGetInfo(0, 2, 0)]

语法

pca

12、panim

作用

显示是否正在执行动画,相当于调用p (BOOL)[UIView _isInAnimationBlock]

语法

panim

三、Find

1、fvc

作用

根据viewController的Class名字查找VC

语法

fvc [--name=classNameRegex] [--view=view]

  • --name/-n: string类型参数,根据viewController的Class名字查找viewController
  • --view/-v: UIView类型参数,根据viewController拥有的view查找viewController

上面2个option不能同时使用,只能使用某一个

2、fv

作用

根据view的class名字查找view

语法

fv classNameRegex

  • classNameRegex: view的class名称

3、taplog

作用

将点击的view打印出来,这个语法对于查找哪个view非常有帮助

语法

taplog

  • 要查看的view必须能接收点击事件,也就是他的userInteractionEnabled必须为YES才能被找到,UILabel和UIImageView默认userInteractionEnabled为NO。
用法

先将程序暂停,输入taplog,程序会自己运行,这时候点击你需要查看的view,控制台上就会显示出你刚刚点击的view相关信息

4、flicker

作用

将view闪烁一下,以便于查找view的位置

语法

flicker viewOrLayer

flicker self.view

  • viewOrLayer需要闪烁的view或者layer

5、vs

作用

在view层级中搜索view,并显示出来

语法

vs view

  • 相比fv,vs主要用于显示view在屏幕上的位置,2个语法可以配合使用
  • 控制台中vs的view也有相应log。并且还提示有6种子语法:
    • w: 移动到superview
    • s: 移动到第一个subview
    • a: 移动到前面的同级view
    • d: 移动到后面的同级view
    • p: 打印出层级
    • q: 退出

四、Display

debug的时候,可能有一小半的工作是跟UI打交道,关于UI显示上的东西,也有几个语法

1、caflush

作用

刷新UI界面。一般我们用LLDB语法改变UI,UI并不会立即更新,我们需要使用caflush刷新界面

语法

caflush

2、border

作用

给View或者layer加上border

语法

border [--color=color] [--width=width] viewOrLayer

  • --color/-c: 边框颜色,string类型,比如:’red’, ‘green’ ‘magenta’等,不设置默认为红色
  • --width/-w: 边框宽度,不设置默认为2
  • viewOrLayer: 需要设置边框的view或者layer

3、unborder

作用

去掉view或者layer的border

语法

unborder

4、mask

作用

给view添加一个半透明的矩形mask,用来查看view的位置

语法

mask [--color=color] [--alpha=alpha] viewOrLayer

  • --color/-c: mask的颜色,string类型,比如:’red’, ‘green’,’magenta’等,不设置默认为红色
  • --alpha/-a: mask的透明度,不设置默认为0.5
  • viewOrLayer: 需要添加mask的view或者layer

5、unmask

作用
语法

unmask viewOrLayer

6、show

作用

显示一个view或者layer,相当于执行view.hidden = NO

语法

show viewOrLayer

7、hide

作用

隐藏一个view或者layer,相当于执行view.hidden = YES

语法

hide viewOrLayer

8、slowanim

作用

减慢动画的速度

语法

slowanim speed

  • speed: 动画的速度,速度越大,动画越快。1表示原始速度。不传参数默认为0.1

9、unslowanim

作用

取消slowanim效果,将动画速度变为正常

语法

unslowanim

五、Preview 预览

预览功能,帮助我们用语法查看一个view或者图片的真正样子

1、visualize

作用

用预览App打开UIImage, CGImageRef, UIView, CALayer等对象

语法

visualize target

六、Debug

Chisel的debug相关语法。

1、wivar

作用

为对象的成员变量设置watchpoint

语法

wivar object ivarName

watchpoint delete

  • object: 需要为成员变量设置watchpoint的对象。id类型
  • ivarName: 成员变量的名字,注意一般属性对应的成员变量带有**_前缀**
  • 这时候,ivarName值改变就会中断程序

2、bmessage

作用

根据方法名设置断点

语法

bmessage expression

  • expression: 设置断点的方法名,如: -[MyView setFrame:], +[MyView awesomeClassMethod], -[0xabcd1234 setFrame:]等
  • 一般设置断点,如果这个方法本类没有实现,是父类实现的,断点是无效的。bmessage有效避免了这种缺陷,即使本类没有实现,也能设置上断点

3、bdisable

作用

设置断点无效

语法

bdisable address

bdisable fileName

bdisable module(AppName)

4、benable

作用

设置断点有效

语法

benable address

benable fileName

benable module(AppName)

5、binside

作用

通过一个相对地址,给framework(library)设置断点

语法

binside address

6、pinvocation

作用

打印方法调用堆栈,仅支持x86

语法

pinvocation [--all]

  • --all/-a: 表示打印所有堆栈,不设置默认只打印当前堆栈
  • 与bt语法类似,不过信息比bt打印得更详细,遗憾的是只能支持x86

七、Accessibility

这个模块的语法主要利用了UIAccessibility相关特性,需要开启Accessibility功能才能使用

1、fa11y

作用

根据view的accessibilityLabel查找view

语法

fa11y labelRegex

fa11y 妈妈 --> (UILabel 0x176b5bd0) 妈妈叫你回家吃饭了

  • labelRegex: 需要匹配的text
  • UILabel,UIButton的accessibilityLabel等于title

2、pa11y

作用

打印view层级中所有的accessibilityLabel

语法

pa11y aView

  • aView: 需要打印层级的View,UIView类型