GDB-Python-scripting: alle Proben Durchlaufen C/C++ - struct-Felder

Den neuen GDB-Python-scripting-API sieht Recht mächtig und sollte sehr nützlich sein. Jedoch schreiben ein nützliches script zum Durchlaufen der Felder in einem struct in C oder C++ ist nicht trivial. Hat jemand wissen, einige Feste Proben, was genau das macht?

Vielen Dank im Voraus.


Update die endgültige Stichprobe: Ersetzen Sie die _print_fields() im frühen Probe.

    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

Und die Ausgabe:

  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

Update mit der ersten Probe: haben Sie das folgende Beispiel-code funktioniert. Dies ist nicht das optimale, wie es ist ein look-up auf jedes Feld nach dem verfassen des string-Feld name. abarnert zeigt eine vielversprechende und eleganten Ansatz, den funktionierenden code aktualisiert wird, der oben in der letzten update-Abschnitt.

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()

Der source-Datei zu testen mit:

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

Beispiel-Ausgabe:

  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-Sitzung zu bekommen:
Quelle /home/me/testpath/wzdfile.py
Datei ein.aus
b main
r
wzd s1
beenden Sie

  • Haben Sie versucht, Suche durch die Python-Quelltext für die pretty-printers, die mit gcc und gdb? Es müssen gute Beispiele gibt.
  • Sind Sie mit Python 2.x, oder 3.x? Was ich sagen kann, gdb kann nun entweder. Und die gdb-docs bedeuten, dass die Arten sind effektiv ausgesetzt, wie python dict Objekte. Und die API für dict Objekte ist der Unterschied zwischen den beiden Versionen. (Zum Beispiel in 2.x, iteritems() gibt eine lazy iterator über die Schlüssel-Wert-Paare, während items() gibt eine Liste von Schlüssel-Wert-Paare; in 3.x, items() gibt eine lazy-iterator, und es gibt keine iteritems().)
  • python 2.6.6, gdb-7.2, x86_64
InformationsquelleAutor minghua | 2013-02-05
Schreibe einen Kommentar