gpt4 book ai didi

ios - LLDB Python 访问 iOS 变量?

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:04:04 25 4
gpt4 key购买 nike

作为调试可能与我的 UIVIews 相关的问题的一部分,我想编写一个从 LLDB 运行的 python 脚本。我曾想在断点和所有 View 子项中提取 View 的所有设置,以允许我比较状态。我查看了有关该主题的 WWDC 视频,然后花时间阅读 lldb.llvm.org/scripting.html 上的内容,但没有发现它们很有帮助。在网络上搜索示例,结果与这些示例没有实质性不同。

我的问题是我试图弄清楚如何在我的断点处访问 iOS 变量。我见过的示例执行诸如转换数字和模拟 shell 命令之类的操作。有趣的东西,但对我的目的没有用。我一直在阅读“脚本帮助(lldb.SBValue)”等帮助信息,但进展缓慢,因为结果很大,而且不清楚使用模式是什么。我觉得如何遍历一些 iOS 对象的一个​​体面的例子会帮助我理解这个系统。有谁知道一个或可以分享一段代码吗?

更新:

我写这篇文章是为了帮助我追踪 UIView 使用中的错误。我想做更多的工作来改进它,看看我是否可以显示整个 View 树,但这足以解决我的问题,所以我将它放在这里以节省其他人一些时间。

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”。

最佳答案

也许这会有所帮助。下面是一个如何在遇到断点时转储简单局部变量的示例。我没有正确显示 char* 数组,我不确定我应该如何获取这些数据来显示它,就像“框架变量”会显示它一样,但我稍后会在有空的时候弄清楚。

struct datastore {
int val1;
int val2;
struct {
int val3;
} subdata;
char *name;
};

int main (int argc, char **argv)
{
struct datastore data = {1, 5, {3}, "a string"};
return data.val2;
}

Current executable set to 'a.out' (x86_64).
(lldb) br se -l 13
Breakpoint created: 1: file ='a.c', line = 13, locations = 1
(lldb) br comm add -s python
Enter your Python command(s). Type 'DONE' to end.
> def printvar_or_children(var):
> if var.GetNumChildren() == 0 and var.IsInScope():
> path = lldb.SBStream()
> var.GetExpressionPath(path)
> print '%s: %s' % (path.GetData(), var.GetValue())
> else:
> for subvar in var:
> printvar_or_children(subvar)
>
> print 'variables visible at breakpoint %s' % bp_loc
> for var in frame.arguments:
> printvar_or_children(var)
> for var in frame.locals:
> printvar_or_children(var)
>
> DONE
(lldb) r
variables visible at breakpoint 1.1: where = a.out`main + 51 at a.c:13, address = 0x0000000100000f33, resolved, hit count = 1
argc: 1
*(*(argv)): '/'
data.val1: 1
data.val2: 5
data.subdata.val3: 3
*(data.name): 'a'
Process 84865 stopped
* thread #1: tid = 0x1f03, 0x0000000100000f33 a.out`main + 51 at a.c:13, stop reason = breakpoint 1.1
frame #0: 0x0000000100000f33 a.out`main + 51 at a.c:13
10 int main (int argc, char **argv)
11 {
12 struct datastore data = {1, 5, {3}, "a string"};
-> 13 return data.val2;
(lldb)

提示 - 为了理智起见,我在侧边文本编辑器中处理了 python,并在试验时将其粘贴到 lldb 中。

如果您在 lldb 中使用 frame variable 命令在给定的停止位置探索您的变量,这与您可以通过提供给“frame”对象中的断点 python 命令的 SBFrame 访问它们的基本方式相同。

希望这有助于您入门。

关于ios - LLDB Python 访问 iOS 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12668815/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com