为了避免浪费你的时间,在阅读本文前,请先思考以下问题:
如果都是NO,那么,请先阅读 与调试器共舞 - LLDB 的华尔兹[1] 后再回来阅读本文章。相信我,掌握甚至精通 lldb 能够快速的提供你的生产力。
如果以上问题都是YES,那么,欢迎继续阅读以下内容。
阅读本文需要以下技能:
通过本文,希望大家可以了解以下内容:
LLDB 是一个开源调试器,它已经被内置在 Xcode 程序中。如下图所示,位于主窗口的底部,名为Conseole的窗口就是用于和 lldb 交互的区域。
x
首先,我们先通过以下步骤对 lldb 进行初步的了解。
viewDidLoad
处添加添加断点po self
并回车当程序暂停后(通过断点或者手动点击暂停按钮),Console 区域就会进入 lldb 模式。po self
是指把 self 当做一个对象进行打印,类似的还有 p self
等命令。
ps. 通过
help
命令,可以打印所有的可用命令。pss. 通过help po
命令,可以打印该命令的用法。
Chisel 是一个 Python 脚本集合,建议读者先阅读 与调试器共舞 - LLDB 的华尔兹 后再看下面的部分
LLDB 的调试接口本质上是一个 C++ 共享库,在 Mac 系统上,它被打包为 LLDB.framework(正常情况下,我们可以 /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework
路径看到它),在类 unix 系统上,它是 lldb.so。这些调试接口可以在 lldb 的脚本解释器内直接使用,或者可以被引入 lldb.py 模块的 Python 脚本使用。
LLDB 本身支持用户自定义命令,比如通过脚本可以自定义一个pviews
命令,该命令可以打印 APP 所有的视图。
该命令已经在 Chisel 中实现。
首先,我们先通过一个非常简单的脚本,构造一个自定义命令。
在~/ls.py 位置创建一个脚本,内容如下:
import lldb
import subprocess
def ls(debugger, command, result, internal_dict):
print(command)
ret = subprocess.getstatusoutput('ls ' + command)
for i in ret[1].split("\n"):
print(i)
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('command script add -f ls.ls ls')
print ('The "ls" python command has been installed and is ready for use.')
(lldb) command script import ~/ls.py
(lldb) ls ./
Applications
Users
...
到此为止,我们已经成功的实现了一个自定义的命令。
OK,让我们重新解释一下上面的代码。
command script import ~/ls.py
command
是 lldb 用于管理自定义命令的一个入口。
command script import
可以导入一个自定义的脚本文件。
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('command script add -f ls.ls ls')
print 'The "ls" python command has been installed and is ready for use.'
脚本文件被导入时,并且def __lldb_init_module(debugger, internal_dict):
方法会被检测到时,它会被自动调用。我们可以在这里一次性实现多个自定义命令。
debugger
是 lldb.SBDebugger
lldb.SBDebugger-class[3] 的一个实例,代表了当前的调试器对象。
internal_dict
包含了当前脚本会话的变量和方法。
HandleCommand
是一个实例方法,通过它,我们可以在 Python 脚本里面,调用 lldb 的方法。比如,这里的command script add -f ls.ls ls
command script add -f ls.ls ls
的含义是“声明一个自定义的命令ls
,这个命令的实现是 ls.ls
”。command script add -f 函数名 自定义命令名
-f
代表后面跟着一个函数名,类似还有-c
,代表一个 Python 类。
import lldb
import subprocess
def ls(debugger, command, result, internal_dict):
print(command)
ret = subprocess.getstatusoutput('ls ' + command)
for i in ret[1].split("\n"):
print(i)
debugger
上面已经讲过,不再赘述。
command
是一个字符串,是我们命令的参数。以我们在 lldb 输入 ls -l var
为例,command
是-l var
。
result
是lldb.SBCommandReturnObject
的实例。
internal_dict
上面已经讲过,不再赘述。
这个函数是我们自定义命令的核心,它通过调用 Python 模块 subprocess
的 getstatusoutput
方法,获取ls
命令的输出结果,并打印到结果中。
通过上面的介绍,相信我们很容易实现一个批量管理断点的自定义命令。
这里简单分享一下思路。
benable
&bdisable
def switchBreakpointState(expression,on):
#!/usr/bin/python
import lldb
import optparse
import shlex
import re
def switchBreakpointState(expression, on):
expression_pattern = re.compile(r"{}".format(expression), re.I)
target = lldb.debugger.GetSelectedTarget()
for breakpoint in target.breakpoint_iter():
if breakpoint.IsEnabled() != on and (
expression_pattern.search(str(breakpoint))
):
print(str(breakpoint))
breakpoint.SetEnabled(on)
for location in breakpoint:
if location.IsEnabled() != on and (
expression_pattern.search(str(location))
or expression == hex(location.GetLoadAddress())
):
print(str(location))
location.SetEnabled(on)
def benable(debugger, command, result, internal_dict):
switchBreakpointState(str(command),True)
def bdisable(debugger, command, result, internal_dict):
switchBreakpointState(str(command),False)
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('command script add -f ls.ls ls')
debugger.HandleCommand('command script add -f ls.benable benable')
debugger.HandleCommand('command script add -f ls.bdisable bdisable')
print 'The python commands has been installed and is ready for use.'
[1]
与调试器共舞 - LLDB 的华尔兹: https://objccn.io/issue-19-2/
[2]
Xcode 断点文档: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/debugging_with_xcode/chapters/quickstart.html#//apple_ref/doc/uid/TP40015022-CH7-SW3
[3]
lldb.SBDebugger-class: https://lldb.llvm.org/python_reference/lldb.SBDebugger-class.html
[4]
lldb 命令: http://lldb.llvm.org/lldb-gdb.html
[5]
LLDB Python Reference: http://lldb.llvm.org/python-reference.html
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有