开始学习LLDB命令(第三章:使用LLDB附加)

现在你已经学到了两个最基本的命令aproposhelp.是时候研究一下LLDB是如何把自己附加到进程上的.你会学习到所有用不同的选项把LLDB附加到进程上的不同方法, 以及附加到进程后会发生什么.
附加attaching这个单词多少有点误导.一个叫debugserver的程序(可以在Xcode.app/Contents/SharedFrameworks/LLDB.framework/ Resources/里找到), 负责附加到目标进程上.
如果要附加的是一个远程进程, 比如是一个运行在iOS, watchOS或者tvOS的设备上的应用程序, 一个远程debugserver会在那个远程设备上启动.启动, 连接和使用debugserver定位来处理在调试应用程序过程中所有的交互是LLDB的工作.

附加到已经存在的进程上

就像你再第一章中看到的, 你可以用下面的命令附加到一个进程上:

lldb -n Xcode

然而, 我们还有另外一种方法做这件事!你可以通过使用进程标识符或者PID将LLDB附加到正在运行的进程上.
打开Xcode, 然后打开一个新的终端窗口, 然后运行下面的命令:

pgrep -x Xcode

这条命令会输出Xcode进程的PID.
然后, 运行下面这条命令, 并把89944用上面得到的PID替换掉:

lldb -p 89944

这条指令告诉LLDB用用指定的PID附加到进程上.在这里就是Xcode的进程.

附加到一个将来的进程上

上面的命令只能附加到正在运行的进程上.如果Xcode没有运行, 上面的命令就会失效.如何在你还不知道进程PID的情况下捕获到即将启动的进程呢?
你可以使用-w参数做到, 这会让LLDB进入等待状态直到特定PID的进程启动或者可执行文件的名字与-w的参数一致的时候.
例如, 在终端里按下Ctrl + D杀掉已经存在的LLDb进程, 然后输入下面的命令:

lldb -n Finder -w

这条命令会让LLDB附加到一个下次启动的名字叫Finder的进程上. 然后打开一个新的终端窗口, 并输入一下命令:

pkill Finder

这条命令会杀掉Finder进程并强制重启Finder进程.
macOS会自动重启Finder当Finder被杀掉的时候.切换到你第一次创建的终端窗口中, 你会发现LLDB已经附加到了最近创建的Finder进程上.
另外一个附加到指定进程的方法是指定可执行文件的路径, 并在你方便的时候手动启动进程.

lldb -f /System/Library/CoreServices/Finder.app/Contents/MacOS/Finder

这会将Finder设置为可执行文件启动.一旦你准备好开始调试了, 只需在LLDB会话中简单的输入下面的命令:

(lldb) process launch
注意:一个有趣的现象是当你手动启动一个进程的时候stderr会自动发送到终端窗口. 用其他方法附加LLDB的时候不会自动做这件事.
启动时的选项

进程启动命令有一些选项值得我们进一步探索.如果你感觉好奇并且想知道启动进程时可用选项的完整列表, 只需要简单键入help process launch.
关闭前面的LLDB会话, 打开一个新的终端窗口并且输入下面的命令:

lldb -f /bin/ls

这条命令告诉LLDB使用/bin/ls(文件列表命令)作为可执行文件.
你会看到下面这些输出:

 (lldb) target create "/bin/ls"
Current executable set to '/bin/ls' (x86_64).

鉴于ls是一个很迅速的程序(它会启动, 完成它的工作, 然后退出),你将会用不同的参数多次运行这个程序来浏览每次都做了什么.
第一次先尝试在没有参数的情况下启动ls. 输入下面的命令:

(lldb) process launch

你将会看到下面的输出:

Process 7681 launched: '/bin/ls' (x86_64)
... # Omitted directory listing output
Process 7681 exited with status = 0 (0x00000000)

一个ls进程将会在你当前的工作目录里启动.你也可以用-w选项告诉LLDB改变当前的工作目录.
输入下面的命令:

 (lldb) process launch -w /Applications

这条命令会在/Applications目录下启动ls程序.
这条命令等价于下面这条命令:

$ cd /Applications
$ ls

我们还有另外一条方法来做到同样的事情.取而代之的是你可以告诉LLDB运行程的目录, 你可以给程序目录参数传一个值.
输入下面的命令:

(lldb) process launch -- /Applications

这条命令与之前的命令拥有同样的效果, 但是这一次他做了下面的事情:

$ ls /Applications

这一次, 会罗列出你macOS中所有的应用程序, 但是你指定了一个参数改变了ls启动的目录.怎样将你桌面的目录作为启动参数呢?键入下面的命令:

(lldb) process launch -- ~/Desktop

你会看到下面的输出:

Process 8103 launched: '/bin/ls' (x86_64)
ls: ~/Desktop: No such file or directory
Process 8103 exited with status = 1 (0x00000001)

呃, 不起作用?你需要展开一下shell的参数.用下面的命令再试一次:

(lldb) process launch -X true -- ~/Desktop

-X参数可以展开你提供的任何shell参数, 比如~.
这里有一个LLDB指令的快捷键:run.要学习更多创建自己命令的快捷键的, 请参考第八章"Persisting and Customizing Commands".
输入下面的命令来查看run命令的文档:

(lldb) help run

你会看到下面的输出:

...
Command Options Usage:
  run [<run-args>]
'run' is an abbreviation for 'process launch -X true --'

这是你刚刚运行的命令的缩写.只需键入下面的命令去运行:

(lldb) run ~/Desktop

如何改变输出的位置?在第一章中你已经试过用-e参数将stderr输出到不同的终端窗口中, 但是改变stdout的位置如何做呢?
尝试键入下面的命令:

(lldb) process launch -o /tmp/ls_output.txt -- /Applications

-o选项告诉LLDB将stdout输出到指定的文件中.
你将会看到下面的输出:

Process 15194 launched: '/bin/ls' (x86_64)
Process 15194 exited with status = 0 (0x00000000)

注意这里并没有直接从ls中输出.
打开下面的命令并运行下面的命令:

cat /tmp/ls_output.txt

正如期望的那样, 这是你应用程序下次输出的目录!
对于stdin同样也有一个-i选项.首先,键入下面的选项:

(lldb) target delete

这条命令移除了作为目标的ls.接下来, 输入下面的命令:

(lldb) target create /usr/bin/wc

这一条命令将/usr/bin/wc作为新的目标.wc可以用来统计stdin输入中的字符, 单词或者行数.
你已经将LLDB的目标可执行文件从ls切换到wc.现在你需要给wc提供一些参数.打开一个新的终端窗口并输入下面的命令:

 echo "hello world" > /tmp/wc_input.txt

你会看到这个文件给wc提供了一些输入.
切换到LLDB会话中, 并输入下面的命令:

(lldb) process launch -i /tmp/wc_input.txt

你将会看到下面的输出:

Process 24511 launched: '/usr/bin/wc' (x86_64)
       1       2      12
Process 24511 exited with status = 0 (0x00000000)

这等价于下面这条命令:

$ wc < /tmp/wc_input.txt

有时你不想用stdin(standard input). 这对像Xcode这样的GUI程序是非常有用的, 但是对于像lswc这样的终端命令来说没有实质性的帮助.
举例说明你一下, 不用任何参数运行wc程序, 键入下面的内容:

(lldb) run

这个程序将只是挂在那里因为它希望从stdin里读到一些输入.
键入hello world来给它一些输入, 在字符的结尾处, 按下Return, 然后按下Control + D.wc会分析这些输入并且退出.你将会看到同你前面用文件作为输入的时候的同样的输出.
现在, 用下面的命令启动进程:

(lldb) process launch -n

你会看到wc立刻退出, 并看到下面这些输出:

 Process 28849 launched: '/usr/bin/wc' (x86_64)
Process 28849 exited with status = 0 (0x00000000)

-n选项告诉LLDB不要创建一个stdin.一次wc没有可以处理的数据并且立即退出.
我们为什么要学习这些东西?
还有一些更有趣的选项可以用, 你会在后面的章节里看到它们.在后面的章节中, 你将会学到LLDB如何将自己附加到iOS设备的远程debugsever上.
从现在开始尝试附加到非GUI程序上就像附加到GUI程序上那样.尝试在终端中运行你期望的stdin或者参数, 然后看看你发现了什么?

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

推荐阅读更多精彩内容