相当于 lldb 中的 python gdb.execute('...')
An equivalent to python gdb.execute('...') in lldb
如果我有这样的结构(在 C 中)
typedef struct {
int x;
int[2] y;
} A;
和它的一个实例,比如 a
和 a.x=1
和 a.y={2,3}
。
要从 python 脚本访问 a.y[1]
,我真的必须执行这个非常冗长的命令吗?
script print lldb.frame.FindVariable('a').GetChildMemberWithName('y').GetChildAtIndex(1)
当我想在 C:
中打印结构变量的成员时,我编写了这个函数来帮助我
# lldb_cmds.py
import lldb
def get_nested_val_c(vnames,idx=None):
"""
vnames is a list of strings ['a','b','c',...] that will be evaluated as if
you called
a.b.c.,...
So for [a,b,c] you get:
a.b.c
If idx is given, it is evaluated as
a.b.c[idx]
"""
try:
x=lldb.frame.FindVariable(vnames[0])
for v_ in vnames[1:]:
x=x.GetChildMemberWithName(v_)
except TypeError:
x=lldb.frame.FindVariable(vnames)
if idx == None:
return x
try:
x=x.GetChildAtIndex(idx[0])
for i_ in idx[1:]:
x=x.GetChildAtIndex(i_,False,True)
except TypeError:
x=x.GetChildAtIndex(idx)
然后可以用
加载
command script import lldb_cmds.py
并调用(如上)
python lldb_cmds.get_nested_val_c[['a','y'],1)
但是有没有更短的路呢?是的,我知道你可以写
p a.y[1]
但是由于 lldb 中似乎没有任何 while 循环,我如何在不诉诸如此长的语句的情况下使用可变索引打印它?
(是的,我知道你可以为这个例子写:p *(int(*)[2])a.y
但我问的是一般情况。)
我不完全确定你想在这里做什么。我会回答几个潜在的问题,你可以告诉我其中一个是否正确...
如果您正在尝试找到一种更好的方法来访问已知的嵌套结构,这可能会更方便:
var = lldb.frame.FindVariable("a").GetValueForExpressionPath("y[0]")
如果您尝试在 Python 脚本中执行 运行 命令行命令,则有两种方法可以执行此操作:
lldb.debugger.HandleCommand("command")
这只是 运行 命令,并将结果打印到 lldb 的标准输出,或者:
ret_val = lldb.SBCommandReturnObject()
lldb.debugger.GetCommandInterpreter().HandleCommand("command", ret_val)
这会将 运行 命令和 return 命令的结果(在 lldb 驱动程序中打印为命令 运行s 的结果)放入 ret_val
对象。如果您想检查命令的结果,这很方便。 ReturnObject 还会告诉您命令是否成功,如果不成功则保留错误。
如果您尝试打印静态分配的数组 - 如您的示例所示 - 您不需要执行上面显示的转换,您应该能够执行以下操作:
(lldb) p a.y
这应该会打印所有元素。如果您正在处理动态大小的数组(例如,您指向 malloc 数组的 int *),Xcode 8.0 中的 lldb 有一个新命令 parray
让您说:
(lldb) parray 10 a.y
打印 y 指向的整数数组的 10 个元素。
如果我有这样的结构(在 C 中)
typedef struct {
int x;
int[2] y;
} A;
和它的一个实例,比如 a
和 a.x=1
和 a.y={2,3}
。
要从 python 脚本访问 a.y[1]
,我真的必须执行这个非常冗长的命令吗?
script print lldb.frame.FindVariable('a').GetChildMemberWithName('y').GetChildAtIndex(1)
当我想在 C:
中打印结构变量的成员时,我编写了这个函数来帮助我# lldb_cmds.py
import lldb
def get_nested_val_c(vnames,idx=None):
"""
vnames is a list of strings ['a','b','c',...] that will be evaluated as if
you called
a.b.c.,...
So for [a,b,c] you get:
a.b.c
If idx is given, it is evaluated as
a.b.c[idx]
"""
try:
x=lldb.frame.FindVariable(vnames[0])
for v_ in vnames[1:]:
x=x.GetChildMemberWithName(v_)
except TypeError:
x=lldb.frame.FindVariable(vnames)
if idx == None:
return x
try:
x=x.GetChildAtIndex(idx[0])
for i_ in idx[1:]:
x=x.GetChildAtIndex(i_,False,True)
except TypeError:
x=x.GetChildAtIndex(idx)
然后可以用
加载command script import lldb_cmds.py
并调用(如上)
python lldb_cmds.get_nested_val_c[['a','y'],1)
但是有没有更短的路呢?是的,我知道你可以写
p a.y[1]
但是由于 lldb 中似乎没有任何 while 循环,我如何在不诉诸如此长的语句的情况下使用可变索引打印它?
(是的,我知道你可以为这个例子写:p *(int(*)[2])a.y
但我问的是一般情况。)
我不完全确定你想在这里做什么。我会回答几个潜在的问题,你可以告诉我其中一个是否正确...
如果您正在尝试找到一种更好的方法来访问已知的嵌套结构,这可能会更方便:
var = lldb.frame.FindVariable("a").GetValueForExpressionPath("y[0]")
如果您尝试在 Python 脚本中执行 运行 命令行命令,则有两种方法可以执行此操作:
lldb.debugger.HandleCommand("command")
这只是 运行 命令,并将结果打印到 lldb 的标准输出,或者:
ret_val = lldb.SBCommandReturnObject()
lldb.debugger.GetCommandInterpreter().HandleCommand("command", ret_val)
这会将 运行 命令和 return 命令的结果(在 lldb 驱动程序中打印为命令 运行s 的结果)放入 ret_val
对象。如果您想检查命令的结果,这很方便。 ReturnObject 还会告诉您命令是否成功,如果不成功则保留错误。
如果您尝试打印静态分配的数组 - 如您的示例所示 - 您不需要执行上面显示的转换,您应该能够执行以下操作:
(lldb) p a.y
这应该会打印所有元素。如果您正在处理动态大小的数组(例如,您指向 malloc 数组的 int *),Xcode 8.0 中的 lldb 有一个新命令 parray
让您说:
(lldb) parray 10 a.y
打印 y 指向的整数数组的 10 个元素。