gdb python : Can anyone explain me how to use this

2020-03-31 04:52发布

How to do it for a c code..? Is it possible..? I read this post. I also want to do similar things but i am not able to use the given updated script at link GDB-Python scripting: any samples iterating through C/C++ struct fields

I followed the following steps to test : my source code name was : test.c and pretty.py

gcc -g test.c

gdb test

(gdb) source pretty.py

(gdb) run

(gdb) print <stcruct object>

How to use this script?

1条回答
Luminary・发光体
2楼-- · 2020-03-31 05:27

That script implements a new GDB command, wzd which takes a C structure as argument. You can tell from the Python doc string after class PrintGList

"""print fields of a struct: wzd struct_object
Iterate through the fields of a struct, and display
a human-readable form of the objects."""

You were expecting the script to implement a GDB pretty printer for a custom data type and change what gets printed when you use GDB's print command but that's not how the script is hooked up.

The class name PrintGList suggests that code originated from a script that printed the linked lists in the glib library. Copy and paste coding strikes again ;) I've fixed a few minor bugs and cleaned up the code below (wzd.py):

import gdb

def _type_is_container(t):
    return t.code == gdb.TYPE_CODE_STRUCT

class WZD(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])
        (t, m) = (l.type, l.type.tag)

        print "  variable %s " % n, " type %s " % t

        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
            if _type_is_container(x.type):
                tag_msg = ', tag: %r' % (x.type.tag,)
            else:
                tag_msg = ''
            print '  field %r type %s (code: %s%s)' % (sn, x.type, x.type.code, tag_msg)
            if _type_is_container(x.type):
                print "Found sub level struct  %s " % sn
                sl = gdb.parse_and_eval(sn)
                sm = sl.type.tag
                st = sl.type
                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

WZD()

Test program (struct-read.c):

#include <assert.h>
#include <stdio.h>

/* https://github.com/scottt/debugbreak */
#include <debugbreak/debugbreak.h>

struct T {
    int x, y;
};

struct S {
    struct T t;
    char b;
};

int main()
{
    int r;
    struct S s;
    r = scanf("%d%d%c", &s.t.x, &s.t.y, &s.b);
    assert(r == 3);
    debug_break();

    return 0;
}

Sample GDB session:

$ echo 1 2 x > in
$ gdb -q -x wzd.py struct-read
<...>

(gdb) run < in
<...>
Program received signal SIGTRAP, Trace/breakpoint trap.
main () at struct-read.c:25
25  }

(gdb) wzd s
  variable s   type struct S 
Found a struct  s 
struct S
  field 's.t' type struct T (code: 3, tag: 'T')
Found sub level struct  s.t 
struct T
  field 's.t.x' type int (code: 8)
  field 's.t.y' type int (code: 8)
  field 's.b' type char (code: 8)
查看更多
登录 后发表回答