struct net_device
, struct pci_dev
Linux 中的代码旨在由内核而不是用户空间代码使用。它们甚至没有导出到您获得的经过清理的内核标头中make headers_install
与 libc 一起使用。
GDB无法打印struct net_device
, struct pci_dev
因为它没有描述这些结构定义的调试信息。您的用户空间struct my_struct
被声明为具有指向这些结构的不透明指针。我认为你一开始就不应该这样做。
核心转储澄清后编辑
诀窍是将调试信息从内核和驱动程序模块加载到 GDB 中:
- 使用 debuginfo 获取内核(配置调试信息)。例如对于 Centos,获取匹配的内核调试信息包裹来自http://debuginfo.centos.org/6/x86_64/.
- Get the .text, .data and .bss通过检查加载驱动程序模块的地址/系统/模块/我的司机/sections/{.text,.data,.bss}来自在正常操作下运行驱动程序的系统。
假设带有调试信息的内核位于/usr/lib/debug/lib/modules/3.9.4-200.fc18.x86_64/vmlinux, run:
$ 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
更换时文本地址, 数据地址 and BSS-ADDR使用 /sys/module/ 下文件的地址我的司机/部分/。 (我认为在这种情况下,只是撒谎并使用地址 0 可能会起作用)
验证一下ptype 结构体net_device, ptype 结构 pci_dev, ptype my_struct工作。然后得到a的地址后struct *my_struct
就像您之前所做的那样,您应该能够打印其内容。
跟随指针遍历结构体
打印结构跟随指针.py
import gdb
def is_container(v):
c = v.type.code
return (c == gdb.TYPE_CODE_STRUCT or c == gdb.TYPE_CODE_UNION)
def is_pointer(v):
return (v.type.code == gdb.TYPE_CODE_PTR)
def print_struct_follow_pointers(s, level_limit = 3, level = 0):
indent = ' ' * level
if not is_container(s):
gdb.write('%s\n' % (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