送你一份lldb详解!!

前言

学如逆水行舟,不进则退。共勉!!!

闲来无事,一篇lldb详解送给大家了。

lldb详解

lldb命令

  • t:以二进制格式输出

  • x:以十六进制格式输出

  • o:以八进制格式输出

  • b:1-byte

  • w:2-byte

  • l:4-byte

  • q:8-byte您可能会看到一个对话框,显示开发人员工具访问需要控制另一个过程才能继续调试。如果出现此提示, 则必须输入用户名和密码才能进行调试。

    如果您希望永久关闭此提示,则可以在终端中运行以下命令:

1|sudo DevToolsSecurity --enable

使用说明

  • --attach-name :告诉调试器以给定名称附加到进程
  • --attach-pid :告诉调试器使用给定的pid附加到进程
  • -n :--attach-name的别名
  • -p :--attach-pid的别名。
  • --wait-for : 告诉调试器在附加之前等待具有给定pid或名称的进程启动。
  • -w : --wait-for的别名
  • --batch :告诉调试器从-s -S -o和-D运行命令,然后退出
  • -b : --batch别名
  • -K : --source-on-crash的别名
  • -k : --one-on-on-crash的别名
  • --local-lldbinit 允许调试器解析当前工作目录中的.lldbinit文件,除非传递了--no-lldbinit
  • --no-lldbinit : 不要自动解析任何 .lldbinit 文件
  • --one-line-before-file :告诉调试器在加载命令行上提供的任何文件之前执行此单行 lldb命令
  • --one-line-on-crash :在批处理模式下,如果目标崩溃,则告诉调试器运行此单行lldb命令
  • --one-line :告诉调试器在加载命令行上提供的任何文件后执行此单行lldb命令
  • -O : --one-line-before-file :的别名
  • -o : --one行的别名
  • -Q --source-quietly:别名
  • --source-before-file :告诉调试器在加载任何文件之前读入并执行给定文件中的lldb命令。
  • --source-on-crash :在批处理模式下,如果目标崩溃,则告诉调试器为lldb命令提供此文件。
  • --source-quietly :告诉调试器在加载任何文件之前执行此单行lldb命令
  • -S : --source-before-file的别名
  • -s : --source的别名
  • -x : --no-lldbinit别名
  • --arch : 告诉调试器在启动和运行程序时使用指定的体系结构
  • -a : --arch的别名
  • --capture-path :告诉调试器将给定的文件名用于复制器
  • --capture :告诉调试器捕获复制器
  • --core :告诉调试器将 的完整路径用作核心文件
  • -c : --core 的别名
  • --debug :告诉调试器打印出更多信息以进行调试
  • -d : --debug别名
  • --editor:告诉调试器使用主机的“外部编辑器”机制打开源文件。
  • -e : --editor别名
  • --file : 告诉调试器将文件 用作要调试的程序
  • -f : --file的别名
  • --help : 输出LLDB调试器的使用信息
  • -h : --help 的别名
  • --no-use-colors :不要使用颜色
  • --replay : 告诉调试器从重放再现器
  • --reproducer-auto-generate : 退出时生成复制器
  • --reproducer-skip-version-check : 跳过复制器版本检查
  • --version :打印出LLDB调试器的当前版本号
  • -v : --version的别名
  • -X : --no-use-color
  • -r= : --repl=的别名
  • --repl-language :选择REOL的语言
  • --repl = :使用带有给定标志的存根进程以REPL模式运行lldb
  • --repl :使用存根进程以REPL模式运行lldb
  • -R : --reps-language 的别名
  • -r : --repl别名
  • -l : --script-language的别名
  • --python-path : 输出此版本lldb的lldb.py文件的路径
  • -P : --python-path的别名
  • --script-language : 告诉调试器将指定的脚本语言用于用户定义的脚本

打印

1|#查询指定类实现
2|(lldb) type lookup<类名>
3|#获取指定命令帮助
4|(lldb) help <command> <subcommand>
复制代码

设置log输出

1|(lldb) log enable lldb -v -- all
复制代码

设置行号

// The following are the various types of breakpoints that could be set: // 1). -f -l -p -s -g // 2). -a -s -g // 3). -n -s -g // 4). -r -s -g // 5). -p -f (setting a breakpoint by comparing a reg-exp // to source text) // 6). -E -w -h

(lldb) breakpoint set --file test.c --line 12
(lldb) br s -f test.c -l 12
(lldb) b test.c:12

#列出已设置的断点
(lldb) breakpoint list
(lldb) br l
#禁用breakpoint 1 的所有位置
(lldb) break disable 1.*
(lldb) break enable 1.1
# 删除一个断点
(lldb) breakpoint delete 1
(lldb) br del 1
#禁用一个断点
(lldb) breakpoint disable 1
(lldb) br dis 1
# 启用一个断点
(lldb) breakpoint enable 1
(lldb) br en 1
#对指定的函数名下断点
(lldb) breakpoint set --name main
(lldb) br s -n main
(lldb) b main
# 对指定的C++函数名下断点
(lldb) breakpoint set --method main
(lldb) br s -M main
#通过字符串对指定的OC方法函数下断点
(lldb) breakpoint set --name "-[NSString stringWithFormat:]"
(lldb) b -[NSString stringWithFormat:]
#对指定名称的OC Selector下断点
(lldb) breakpoint set --selector count
(lldb) br s -S count
#对符合指定的正则表达式的函数下断点
(lldb) breakpoint set --func-regex regular-expression
(lldb) br s -r regular-expression
(lldb) rb regular-expression
#对指定库中的符合指定的正则表达式的函数下断点
(lldb) breakpoint set --func-regex=. --shlib=libfoo.dylib
#打开行号断点开关
(lldb) settings set target.inline-breakpoint-strategy always
(lldb) br s -f foo.c -l 12
#通过对指定的正则表达式对文件内容设置断点
(lldb) breakpoint set --source-pattern regular-expression --file SourceFile
(lldb) br s -p regular-expression -f file
#设置条件断点
(lldb) breakpoint set --name foo --condition '(int)strcmp(y,"hello") == 0'
(lldb) br s -n foo -c '(int)strcmp(y,"hello") == 0
#### register 
显示当前线程的通用寄存器

(lldb) register read

显示指定的寄存器的内容 (lldb) register read rax rsp rbp

指定寄存器以指定格式显示内容

(lldb) register read --format binary rax (lldb) re r -f b rax (lldb) register read/t rax (lldb) p/t $rax

向指定寄存器写入指定数据 (lldb) register write rax 123

在当前程序计数器(指令指针)之前跳过8个字节 (lldb) register write pc $pc+8

显示格式为带符号十进制的当前线程的通用寄存器 (lldb) register read --format i (lldb) re r -f i (lldb) register read/d

显示当前线程所有的寄存器内容 (lldb) register read --all (lldb) re r -a

#### 启动运行
复制代码

(lldb) process launch (lldb) run (lldb) r

启动附加参数 (lldb) process launch -- (lldb) run (lldb) r % lldb -- a.out 1 2 3 (lldb) run (lldb) run lldb) settings set target.run-args 1 2 3 (lldb) run (lldb) run

#### 设置环境变量
复制代码

在启动之前,设置环境变量 (lldb) settings target.disable-aslr (lldb) settings set target.env-vars DYLD_PRINT_APIS=YES (lldb) set se target.env-vars DYLD_PRINT_APIS=YES (lldb) env DYLD_PRINT_APIS=YES (lldb) settings set target.env-vars DYLD_PRINT_LIBRARIES=1

在启动之前,删除环境变量

(lldb) settings remove target.env-vars DEBUG (lldb) set rem target.env-vars DEBUG

显示将在运行时传递给程序的环境变量 (lldb) settings show target.run-args

通过一个命令为进程和启动进程设置环境变量 (lldb) process launch -v DEBUG=1

附加到进程到指定的ID的进程 (lldb) process attach --pid 123 (lldb) attach -p 123

附加到指定名称的进程 (lldb) process attach --name a.out (lldb) pro at -n a.out

等待指定名称的进程启动并附加 (lldb) process attach --name a.out --waitfor (lldb) pro at -n a.out -w

memory

当前目标进程用于在内存上运行的命令。x是memory read的缩写

#-s(--size):指定内存块(block/item)的大小,默认为1byte̶
# -c( --count)指定内存块(block/item)的个数,可配合起始地址使用
# -f( --format)指定内容显示格式,格式符同printғc-char҅s-string҅d-decimal҅x-hex。

#从指定地址读取内存,并且按格式显示
(lldb) memory read --size 4 --format x --count 4 0xbffff3c0
(lldb) me r -s4 -fx -c4 0xbffff3c0
(lldb) x -s4 -fx -c4 0xbffff3c0

# LLDB now supports the GDB shorthand format syntax but there can't be space after the command:
(lldb) memory read/4xw 0xbffff3c0
(lldb) x/4xw 0xbffff3c0
(lldb) memory read --gdb-format 4xw 0xbffff3c0

# 从指定表达式读取内存
(lldb) memory read `argv[0]`
# NOTE: any command can inline a scalar expression result (as long as the target is stopped) using backticks around any expression:
(lldb) memory read --size `sizeof(int)` `argv[0]`

#从指定地址读取指定大小的内存,并且保存到指定的文件
(lldb) memory read --outfile /tmp/mem.txt --count 512 0xbffff3c0
(lldb) me r -o/tmp/mem.txt -c512 0xbffff3c0
(lldb) x/512bx -o/tmp/mem.txt 0xbffff3c0

# 保存指定范围的内存
(lldb) memory read --outfile /tmp/mem.bin --binary 0x1000 0x2000
(lldb) me r -o /tmp/mem.bin -b 0x1000 0x2000
复制代码

别名

#起别名
(lldb) command alias poc expression -l objc -O --
复制代码

打印数组

# 打印int a[4] = {1,2,3,4};(
lldb) parray 1 &a
复制代码

expression

#启动多行调试命令输出
(lldb) expr

#执行单行命令
(lldb) expr char c[] = "foo"; c[0]

#执行表达式,别名`p <expression>`
(lldb) expression -- <expression>

#`-i <boolean> ( --ignore-breakpoints <boolean> )当表达式在运行时忽略断点
(lldb) expr -i 0 -- function_with_a_breakpoint()

#-u <boolean> ( --unwind-on-error <boolean> )表达式导致崩溃或引发信号
(lldb) expr -u 0 -- function_which_crashes()

#` -l <source-language> ( --language <source-language> )`指定解析表达式时要使用的语言,如果未设置,则使用`target.language`中的设置。`-O ( --object-description )`打印设置API`
(lldb) expression -l objc -O -- [`self.view` recursiveDescription]

# `-L ( --location )`显示变量的位置信息
(lldb) expression -L -- I

# `-f <format> ( --format <format> )`指定显示格式
(lldb) expr -f bin -- (4 * 8) + 5

# `-t <unsigned-integer> ( --timeout <unsigned-integer> )`设置超时时间,默认情况下,表达式在当前线程超时时间为:0.25s。如果在这个时间内不返回,该表达式将中断并恢复线程运行
(lldb) expr -t -- <expression>

# `-Z <count> ( --element-count <count> )`打印数组
(lldb) 'expression -Z 3 -- <value>

#### 汇编
#显示当前函数当前帧的汇编信息
(lldb) disassemble --frame
(lldb) di -f
#显示指定函数的汇编信息
(lldb) disassemble --name main
(lldb) di -n main
#显示指定地址范围的汇编信息
(lldb) disassemble --start-address 0x1eb8 --end-address 0x1ec3
(lldb) di -s 0x1eb8 -e 0x1ec3
#显示指定数量的汇编信息
(lldb) disassemble --start-address 0x1eb8 --count 20
(lldb) di -s 0x1eb8 -c 20
#显示当前函数的当前帧的汇编与源码
(lldb) disassemble --frame --mixed
(lldb) di -f -m
# 显示当前函数的当前帧的汇编与操作码
(lldb) disassemble --frame --bytes
(lldb) di -f -b
# 显示当前帧的当前源码
(lldb) disassemble --line
(lldb) di -l
复制代码

逐行调试

继续执行代码 (lldb) continue (lldb) c( lldb) thread continue

step-over单步调试

(lldb) next (lldb) n (lldb) thread step-over

step-in跳进源码

(lldb) step (lldb) s (lldb) thread step-in #step-out跳出 (lldb) finish (lldb) f (lldb) thread step-out #每次代码停止时,执行固定调试步骤 (lldb) target stop-hook add Enter your stop hook command(s). Type 'DONE' to end.

bt disassemble --pc DONEStop hook #1 added

删除指定的stop-hook

target stop-hook delete 1 #获取stop-hook list target stop-hook list #每次代码停止时,执行指定调试 (lldb) target stop-hook add --one-liner "frame variable argc argv" (lldb) ta st a -o "fr v argc argv" (lldb) display argc (lldb) display argv #只有当停止到指定方法或函数的时候,才执行固定调试 (lldb) target stop-hook add --name main --one-liner "frame variable argc argv" (lldb) ta st a -n main -o "fr v argc argv" #只有当停止到指定类名的时候,才执行固定调试 (lldb) target stop-hook add --classname MyClass --one-liner "frame variable *this" #指定文件 (lldb) target stop-hook add -f main.cpp -l %d -e %d (lldb) ta st a -c MyClass -o "fr v *this" #显示当前源文件中定义的全局/静态变量 (lldb) target variable (lldb) ta v #显示指定的全局变量 (lldb) target variable baz (lldb) ta v baz #显示当前帧的参数和局部变量 (lldb) frame variable (lldb) fr v #显示当前帧的局部变量 (lldb) frame variable --no-args (lldb) fr v -a #显示指定的的局部变量 (lldb) frame variable bar (lldb) fr v bar (lldb) p bar #显示指定输出类型的局部变量 (lldb) frame variable --format x bar (lldb) fr v -f x bar

#### 其他语言
#执行Shell
 (lldb) platform shell <cmd>
 #指定断点触发时,执行相应python脚本,支持ғ"command", "python", "lua", "default-script

 (lldb) breakpoint command add --script-type python 1
 #指定断点触发时,执行相应调试命令
  (lldb) breakpoint command add 1
  # 命名断点,创建断点组`-N <breakpoint-name> ( --breakpoint-name <breakpoint-name> )`
  将断点加入一个断点组
  (lldb) br set -n testStepCommands -N group1 
  (lldb) br set -n testBreakpoints -N group1 
  (lldb) breakpoint disable group1
复制代码

观察点

#无需停止代码即可记录对变量所做的任何更改的方法
#监视变量的赋值操作
(lldb) watchpoint set variable global_var
(lldb) wa s v global_var
#监视某个内存区域的变化。如果未指定监视区域的大小,通过'-x byte_size',则监视区域大小为指针默认的大小
(lldb) watchpoint set expression -- &a
(lldb) wa s e -- &a
#通过条件监视
(lldb) watch set var global(lldb) watchpoint modify -c '(global==5)'
# 显示所有的监视列表
(lldb) watchpoint list
(lldb) watch l
# 删除一个监视点
(lldb) watchpoint delete 1
(lldb) watch del 1
# 指定监视点,执行设置的调试命令
(lldb) watchpoint command add 1
#禁用监视点
(lldb) watchpoint disable
复制代码

福利

分享记录就到这里了 如需iOS资料 请关注主页加入圈子免费获取

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

推荐阅读更多精彩内容