lldb

lldb 调试实战

0x0 命令结构

<noun> <verb> [-options [option-value]] [argument [argument...]]

其中options和argument是可选的.

0x1 常用命令

1,设置断点:

(lldb) br set --file ViewController.m --line 20
Breakpoint 4: where = LLDB`-[ViewController viewDidLoad] + 54 at ViewController.m:20, address = 0x000000010a8f3696

2 ,查看当前thread 的backtrace

thread backtrace 缩写为 bt

* thread #1: tid = 0x82ccc, 0x000000010885d954 LLDB`-[Object init](self=0x000060800000f0f0, _cmd="init") + 20 at main.m:18, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x000000010885d954 LLDB`-[Object init](self=0x000060800000f0f0, _cmd="init") + 20 at main.m:18
    frame #1: 0x000000010885da27 LLDB`main(argc=1, argv=0x00007fff573a26a8) + 71 at main.m:27
    frame #2: 0x000000010c23268d libdyld.dylib`start + 1
    frame #3: 0x000000010c23268d libdyld.dylib`start + 1

3,查询变量
po的作用为打印对象 ,p即是print,也是expression --的缩写,与po不同,它不会打出对象的详细信息,只会打印出一个$符号,数字,再加上一段地址信息。由于po命令下,对象的description 有可能被随便乱改,没有输出地址消息。

2.png

$符号在LLDB中代表着变量的分配。每次使用p后,会自动为你分配一个变量,后面再次想使用这个变量时,就可以直接使用。我们可以直接使用这个地址做一些转换,获取对象的信息

4, watchpoint的作用是监控某一块内存的内容是否发生改变, 如果发生改变则断点断住.

 watchpoint set self->testVar     //为该变量地址设置watchpoint
 
 watchpoint set expression 0x00007fb27b4969e0 //为该内存地址设置
 
 watchpoint,内存地址可从前文提及的`p`命令获取
 
 watchpoint command add -o 'frame info' 1  //为watchpoint 1号加上子命令 `frame info`
 
 watchpoint list //列出所有watchpoint
 
 watchpoint delete // 删除所有watchpoint

0x2 Thread && Frame

用bt 打印出当前线程的堆栈信息,

(lldb) bt
* thread #1: tid = 0x82ccc, 0x000000010885d954 LLDB`-[Object init](self=0x000060800000f0f0, _cmd="init") + 20 at main.m:18, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x000000010885d954 LLDB`-[Object init](self=0x000060800000f0f0, _cmd="init") + 20 at main.m:18
    frame #1: 0x000000010885da27 LLDB`main(argc=1, argv=0x00007fff573a26a8) + 71 at main.m:27
    frame #2: 0x000000010c23268d libdyld.dylib`start + 1
    frame #3: 0x000000010c23268d libdyld.dylib`start + 1

这段backtrace信息中有两种不同类型的信息, 分别是thread 和 frame. 其中thread的格式如下:

(lldb) settings show thread-format
thread-format (format-string) = "thread #${thread.index}: tid = ${thread.id%tid}{, ${frame.pc}}{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}{ at ${line.file.basename}:${line.number}}{, name = '${thread.name}'}{, queue = '${thread.queue}'}{, activity = '${thread.info.activity.name}'}{, ${thread.info.trace_messages} messages}{, stop reason = ${thread.stop-reason}}{\nReturn value: ${thread.return-value}}{\nCompleted expression: ${thread.completed-expression}}\n"

其中关注下thread.index也就是当前的thread索引;frame.pc也就是frame停留位置的指令的地址(pc代表pc寄存器, 存放的是当前指令的地址); thread.queue当前queue的名字.

frame的格式如下:

(lldb) settings show frame-format
frame-format (format-string) = "frame #${frame.index}: ${frame.pc}{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}{ at ${line.file.basename}:${line.number}}{${function.is-optimized} [opt]}\n"

其中关注下frame.index也就是frame的索引;frame.pc也就是停留位置的指令的地址;还有就是方法名称和参数.

上面截出来的信息中, thread #1和frame #1前面有一个*, 代表当前选中的thread和frame.可以通过frame variable命令(缩写fr v)查看当前frame的变量:

0x3 常用的指令

bt // 打出当前thread的backtrace
bt all // 打出所有thread的backtrace
po [SomeClass returnAnObject] // 执行代码并打印出返回值的description
po $x9 = 0 // 直接写寄存器, 不要后面的`= 0`则是把寄存器`x9`的内容打出来
fr v // 打出frame的变量
fr s 1 // 选择frame
br s -n main // 在main方法处下断点
br s -f test.c -l 12 // 在test.c的第12行下断点
b -[NSString stringWithFormat:] // 在这个方法下断点
br s -S count // 给所有的selector是count的方法下断点
br s -n foo -c '(int)strcmp(y,"hello") == 0' // 条件断点
br s -a 0x10002ab0c // 在地址上下断点
br l // 列出所有断点
br del 1 // 删除1号断点, 可以通过 br l查断点号
w s v global_var // 对变量下watchpoint
w s e -- my_ptr // 对指针下watchpoint
w s e 0x10002ab0c //  对地址下watchpoint
w l // 打出watchpoint
w de // 删除watchpoint
ta v foo // 打印全局变量foo
reg re // 打出常用寄存器的内容
x -s4 -fx -c4 0xbffff3c0 // 打出内存内容. 完整命令是: memory read --size 4 --format x --count 4 0xbffff3c0
im list // 列出镜像
im lookup -a 0x00000001875b60fe // 从镜像中查地址对应的内容
im lookup -r -n <FUNC_REGEX> // 从镜像中用正则查出debug符号, 不带-r是不用正则
im lookup -r -s <FUNC_REGEX> // 从镜像中用正则查出非debug符号, 不带-r是不用正则
im lookup -t NSString // 从镜像中查找类型NSString

0x4 参考

LLDB - GETTING STARTED

LLDB - GDB TO LLDB COMMAND MAP

LLDB - STACK FRAME AND THREAD FORMAT

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容

  • 转载 与调试器共舞 - LLDB 的华尔兹: https://objccn.io/issue-19-2/ 推荐:i...
    F麦子阅读 3,332评论 0 10
  • [转]浅谈LLDB调试器文章来源于:http://www.cocoachina.com/ios/20150126/...
    loveobjc阅读 2,506评论 2 6
  • 前言 LLDB是个开源的内置于XCode的具有REPL(read-eval-print-loop)特征的Debug...
    Noskthing阅读 18,485评论 10 89
  • LLDB的Xcode默认的调试器,它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能。平时用Xc...
    小笨狼阅读 20,473评论 31 187
  • 网页布局基础 什么是网页布局?网页布局是网页制作的基础(DIV+CSS网页布局) 分类:流式布局,浮动布局,绝对定...
    单纯的土豆阅读 1,832评论 0 6