作为调试可能与我的 UIVIews 相关的问题的一部分,我想编写一个 python 脚本以从 LLDB 运行。我曾想过在断点和所有视图子项中提取视图的所有设置,以允许我比较状态。我查看了有关该主题的 WWDC 视频,然后花时间阅读 lldb.llvm.org/scripting.html 上的内容,但没有发现它们很有帮助。对示例的网络搜索导致与这些示例没有本质上的不同。
我的问题是我试图弄清楚如何在断点处访问 iOS 变量。我见过的示例执行转换数字和模拟 shell 命令之类的操作。有趣的东西,但对我的目的没有用。我一直在使用“脚本帮助(lldb.SBValue)”等阅读帮助信息,但是由于结果很大并且不清楚使用模式是什么,因此进展缓慢。我觉得如何遍历几个 iOS 对象的一个不错的例子可以帮助我理解系统。有谁知道或可以分享一段代码?
更新:
我写这篇文章是为了帮助我找出 UIView 使用中的错误。我想做更多的工作来完善它,看看我是否可以显示整个视图树,但这足以解决我的问题,所以我将它放在这里以节省其他人一些时间。
import lldb
max_depth = 6
filters = {'_view':'UIView *', '_layer':'CALayer *', '_viewFlags':'struct'}
def print_value(var, depth, prefix):
""" print values and recurse """
global max_depth
local_depth = max_depth - depth
pad = ' ' * local_depth
name = var.GetName()
typ = str(var.GetType()).split('\n')[0].split('{')[0].split(':')[0].strip()
found = name in filters.keys() # only visit filter items children
if found:
found = (filters.get(name) == typ)
value = var.GetValue()
if value is None or str(value) == '0x00000000':
value = ''
else:
value = ' Val: %s' % value
if var.GetNumChildren() == 0 and var.IsInScope():
path = lldb.SBStream()
var.GetExpressionPath(path)
path = ' pathData: %s' % path.GetData()
else:
path = ''
print '^' * local_depth, prefix, ' Adr:', var.GetAddress(), ' Name:', name, ' Type:', typ, value, path
if var.GetNumChildren() > 0:
if local_depth < 2 or found:
print pad, var.GetNumChildren(), 'children, to depth', local_depth + 1
counter = 0
for subvar in var:
subprefix = '%d/%d' % (counter, var.GetNumChildren())
print_value(subvar, depth - 1, subprefix)
counter += 1
def printvh (debugger, command_line, result, dict):
""" print view hierarchy """
global max_depth
args = command_line.split()
if len(args) > 0:
var = lldb.frame.FindVariable(args[0])
depth = max_depth
if len(args) > 1:
depth = int(args[1])
max_depth = depth
print_value(var, depth, 'ROOT')
else:
print 'pass a variable name and optional depth'
我将以下内容添加到我的 .lldbinit 中:
script import os, sys
# So that files in my dir takes precedence.
script sys.path[:0] = [os.path.expanduser("~/lldbpy")]
script import views
command script add -f views.printvh printvh
这样我就可以在 LLDB 提示符下键入“printvh self 3”。