等同于lldb

时间:2016-10-14 20:47:20

标签: python lldb

如果我有这样的结构(在C中)

typedef struct {
    int x;
    int[2] y;
} A;

它的一个实例,用aa.x=1a.y={2,3}

要从python脚本访问a.y[1],我真的必须执行这个非常有用的命令吗?

script print lldb.frame.FindVariable('a').GetChildMemberWithName('y').GetChildAtIndex(1)

当我想在C:

中打印struct变量的成员时,我写了这个函数来帮助我
# 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但我一般都会问。)

1 个答案:

答案 0 :(得分:1)

我不完全确定你想在这里做什么。我会回答几个潜在的问题,你可以告诉我其中一个是否正确......

如果您正在尝试找到更好的方法来进入已知的嵌套结构,这可能会更方便:

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)

这将运行该命令,并将命令的结果(这是lldb驱动程序在命令运行时打印的内容)返回到ret_val对象中。如果要检查命令的结果,这很方便。 ReturnObject还会告诉您命令是否成功,如果不是,则保留错误。

如果您正在尝试打印静态分配的数组 - 如您的示例中所示 - 您不需要执行上面显示的转换,您应该能够:

(lldb)p a.y

那应该打印所有元素。如果你正在处理动态大小的数组(例如你指向malloc的数组的int *),Xcode 8.0中的lldb有一个新的命令parray,可以让你说:

(lldb)参与10 a.y

打印y指向的整数数组的10个元素。