struct net_device,
struct pci_dev在Linux都意味着要使用的内核,而不是用户空间代码。它们甚至没有导出到
makeheaders_install与libc一起使用的经过清理的内核头文件中。
GDB无法打印
struct net_device,
struct pci_dev因为它没有描述这些结构定义的调试信息。您的用户空间
structmy_struct被声明为具有指向这些结构的不透明指针。我不认为您应该首先这样做。
澄清核心转储后进行编辑
诀窍是将调试信息从内核和驱动程序模块加载到GDB中:
- 使用debuginfo( CONFIG_DEBUG_INFO )获取内核。例如对于Centos,从http://debuginfo.centos.org/6/x86_64/获得匹配的 kernel-debuginfo 软件包。
- 通过在正常操作下运行驱动程序的系统中检查 / sys / module / MY-DRIVER /sections/{.text,.data,.bss} ,获取驱动程序模块的 .text , .data 和 .bss 加载地址。 __
假设带有调试信息的内核位于 /usr/lib/debug/lib/modules/3.9.4-200.fc18.x86_64/vmlinux
,运行:
$ gdb /usr/lib/debug/lib/modules/3.9.4-200.fc18.x86_64/vmlinux vmcore(gdb) add-symbol-file MY-DRIVER.ko TEXT-ADDR -s .data DATA-ADDR -s .bss BSS-ADDR
同时用/ sys / module / MY-DRIVER / sections /下文件中的地址替换 TEXT-ADDR , DATA-
ADDR 和 BSS-ADDR 。(我认为在这种情况下,撒谎并使用地址0可能会起作用) __
验证 ptype struct net_device , ptype struct pci_dev 和 ptype
my_struct是否 正常工作。然后,在获得所需的地址后,
struct *my_struct应该可以打印其内容。
跟随指针遍历结构
print-struct-follow-pointers.py
import gdbdef is_container(v): c = v.type.pre return (c == gdb.TYPE_CODE_STRUCT or c == gdb.TYPE_CODE_UNIOn)def is_pointer(v): return (v.type.pre == gdb.TYPE_CODE_PTR)def print_struct_follow_pointers(s, level_limit = 3, level = 0): indent = ' ' * level if not is_container(s): gdb.write('%sn' % (s,)) return if level >= level_limit: gdb.write('%s { ... },n' % (s.type,)) return gdb.write('%s {n' % (s.type,)) for k in s.type.keys(): v = s[k] if is_pointer(v): gdb.write('%s %s: %s' % (indent, k, v)) try: v1 = v.dereference() v1.fetch_lazy() except gdb.error: gdb.write(',n') continue else: gdb.write(' -> ') print_struct_follow_pointers(v1, level_limit, level + 1) elif is_container(v): gdb.write('%s %s: ' % (indent, k)) print_struct_follow_pointers(v, level_limit, level + 1) else: gdb.write('%s %s: %s,n' % (indent, k, v)) gdb.write('%s},n' % (indent,))class PrintStructFollowPointers(gdb.Command): ''' print-struct-follow-pointers [/LEVEL_LIMIT] STRUCT-VALUE ''' def __init__(self): super(PrintStructFollowPointers, self).__init__( 'print-struct-follow-pointers', gdb.COMMAND_DATA, gdb.COMPLETE_SYMBOL, False) def invoke(self, arg, from_tty): s = arg.find('/') if s == -1: (expr, limit) = (arg, 3) else: if arg[:s].strip(): (expr, limit) = (arg, 3) else: i = s + 1 for (i, c) in enumerate(arg[s+1:], s + 1): if not c.isdigit(): break end = i digits = arg[s+1:end] try: limit = int(digits) except ValueError: raise gdb.GdbError(PrintStructFollowPointers.__doc__) (expr, limit) = (arg[end:], limit) try: v = gdb.parse_and_eval(expr) except gdb.error, e: raise gdb.GdbError(e.message) print_struct_follow_pointers(v, limit)PrintStructFollowPointers()样品会议
(gdb) source print-struct-follow-pointers.py(gdb) print-struct-follow-pointers *p
您可以限制打印的嵌入式结构的级别:
(gdb) print-struct-follow-pointers/4 *p



