GDB-Python脚本:通过C / C ++结构域迭代的样本 [英] GDB-Python scripting: any samples iterating through C/C++ struct fields

查看:136
本文介绍了GDB-Python脚本:通过C / C ++结构域迭代的样本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

新的 GDB-Python脚本API 看起来相当强大,应该是非常有用的。但是写一个有用的脚本通过C或C ++的结构领域的迭代是不平凡的。是否有任何人知道,不正是某些固体样品?

The new GDB-Python scripting API looks quite powerful and should be very useful. However writing a useful script to iterate through the fields in a struct of C or C++ is not trivial. Does any one know some solid samples that does exactly that?

在此先感谢。

更新最终样本:早期样品中替换 _print_fields()

Update the final sample: Replace the _print_fields() in early sample.

    if l.type.code == gdb.TYPE_CODE_STRUCT:
        print "Found a struct  %s " % n
        #self._print_fields(n, t)
        self._print_deep_items(n, t, l)
    else:
        print "Found no struct"

def _print_deep_items (self, n_, type_, instance_):
    for fld in type_.fields():
        fn = fld.name
        ft = fld.type
        fv = instance_[fn]
        if fv.type.code == gdb.TYPE_CODE_STRUCT:
            print "  Found a sub struct  %s " % fn
            self._print_deep_items(fn, ft, fv)
        else:
            print "    Field %s " % fn, " type %s " % ft.tag, " value %s " % fv

和输出:

  variable s1   type S1
Found a struct  s1
    Field v1   type None   value 0
    Field v2   type None   value 0
  Found a sub struct  v3
    Field w3   type None   value 0


更新的第一个样本:得到下面的示例code工作。这不是最佳的,因为它确实对每场构成字符串字段名称后的查找。 abarnert呈现出有前途的和优雅的方法,工作code在上述最后更新部分更新。


Update with the first sample: Got the following sample code working. This is not the optimal as it does a look-up on every field after composing the string field name. abarnert is showing a promising and elegant approach, the working code is updated in the above final update section.

import gdb
class PrintGList(gdb.Command):
    """print fields of a struct: wzd struct_object

Iterate through the fields of a struct, and display
a human-readable form of the objects."""
    def __init__(self):
        gdb.Command.__init__(self, "wzd", gdb.COMMAND_DATA, gdb.COMPLETE_SYMBOL, True)

    def invoke(self, arg, from_tty):

        arg_list = gdb.string_to_argv(arg)
        if len(arg_list) < 1:
            print "usage: wzd struct"
            return

        n = arg_list[0]
        l = gdb.parse_and_eval(arg_list[0])
        m = l.type.tag

        print "  variable %s " % n, " type %s " % m
        try:
            t = gdb.lookup_type(m)
        except RuntimeError, e:
            print "type %s not found" % t
            return

        if l.type.code == gdb.TYPE_CODE_STRUCT:
            print "Found a struct  %s " % n
            self._print_fields(n, t)
        else:
            print "Found no struct"

    def _print_fields(self, n, typeobject):
        print typeobject
        flds = typeobject.fields()
        for x in flds:
            sn = n + "." + x.name
            print "  field %s" % sn, " code %s " % x.type.code, " type %s " % x.type.tag
            if x.type.code == gdb.TYPE_CODE_STRUCT:
                print "Found sub level struct  %s " % sn
                sl = gdb.parse_and_eval(sn)
                sm = sl.type.tag
                st = gdb.lookup_type( sm )
                self._print_fields(sn, x.type)

    def _deep_items (self, type_):
        for k, v in type_.iteritems():
            if k:
                print " k v %s " % k , " %s " % v
            else:
                print "   v    ",      " %s " % v

PrintGList()

源文件与测试:

struct S2 {        int w3;    };
struct S1 {        int v1, v2;      struct S2 v3; } s1;
int main(int argc, char *argv[]) {   return 0; }

输出示例:

  variable s1   type S1
Found a struct  s1
S1
  field s1.v1  typecode 8   type None
  field s1.v2  typecode 8   type None
  field s1.v3  typecode 3   type S2
Found sub level struct  s1.v3
S2
  field s1.v3.w3  typecode 8   type None

GDB会得到:
    来源/home/me/testpath/wzdfile.py
    文件为a.out
    b主
     - [R
    WZD S1
    退出

GDB session to get the: source /home/me/testpath/wzdfile.py file a.out b main r wzd s1 quit

推荐答案

据的的文档,通过C结构领域的的是pretty琐碎的迭代:

According to the docs, iterating through the fields of a C struct should be pretty trivial:

如果该类型是一个结构或类类型,或枚举类型,该类型的字段可以使用Python字典语法访问。例如,如果 some_type gdb.Type 实例抱着一个结构类型,您可以访问它foo的领域:

If the type is a structure or class type, or an enum type, the fields of that type can be accessed using the Python dictionary syntax. For example, if some_type is a gdb.Type instance holding a structure type, you can access its foo field with:

bar = some_type['foo']


  
  

将是 gdb.Field 对象;看到下面的 Type.fields 方法的描述下的 gdb.Field 类的描述。

bar will be a gdb.Field object; see below under the description of the Type.fields method for a description of the gdb.Field class.

您也可以使用 Type.fields 来得到,但作为7.4的结构明确,(领域),你可以使用正常的 字典 方法为好,因此要获得名称/ 字段对的列表:

You can also use Type.fields to get the fields of a struct explicitly, but (as of 7.4) you can just use the normal dict methods as well, so to get a list of name/Field pairs:

for name, field in foo.type.iteritems():

或者,只是名称:

Or, for just the names:

for name, field in foo.type.iterkeys():

等。

这似乎没有直接记录在该网页上,但是 gdb.types 意味着它pretty强烈时,它说, deep_items

This doesn't seem to be directly documented on that page, but gdb.types implies it pretty strongly when it says that deep_items:

返回类似标准gdb.Type.iteritems方法一个Python迭代器。

Returns a Python iterator similar to the standard gdb.Type.iteritems method.

例如,鉴于该C型:

struct S {
    int x;
    int y;
};

您可以这样做:

(gdb) python struct_S = my_s.type # or gdb.lookup_type("struct S"), etc.
(gdb) python print struct_S.keys()
{['a', 'b']}
(gdb) python print my_s['a']
0

从在<一个快速浏览href=\"http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/python/lib/gdb/types.py?rev=1.8&content-type=text/x-cvsweb-markup&cvsroot=src\"相对=nofollow> types.py 源,看看如何 gdb.types.deep_item(类型_)实现,这似乎是所有有给它。

From a quick glance at the types.py source, look at how gdb.types.deep_item(type_) is implemented, and that does seem to be all there is to it.

GDB 7.4之前,你不能直接把一个类型为字典。也就是说,没有在instance_.type名称: instance_.type.iteritems(),等你有显式调用字段。无论如何,把他们放在一起,这里是遍历所有的结构领域的使用gdb 7.2一个简单的例子:

Before gdb 7.4, you could not treat a type directly as a dict. That is, no for name in instance_.type: or instance_.type.iteritems(), etc. You had to explicitly call fields. Anyway, putting it all together, here's a simple example for iterating over all of the fields of a structure with gdb 7.2:

for field in inst.fields:
    fname = field.name
    ftype = field.type
    fval = inst[fname]

除这不会,如果你的结构有一个匿名的结构里面工作。对于这一点,你需要 deep_items (如果这是不存在的7.2,你需要看看code和弄清楚如何实现它自己)。

Except that this won't work if your struct has an anonymous struct inside it. For that, you'll need deep_items (and, if that isn't there in 7.2, you'll need to look at the code and figure out how to implement it yourself).

所以,不是的非常的琐碎7.2,但pretty简单。而且,如果你想小事,只要升级到7.4。

So, not quite trivial in 7.2, but pretty simple. And, if you want trivial, just upgrade to 7.4.

这篇关于GDB-Python脚本:通过C / C ++结构域迭代的样本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆