GDB-Python脚本:通过C / C ++结构域迭代的样本 [英] GDB-Python scripting: any samples iterating through C/C++ struct fields
问题描述
新的 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 agdb.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屋!