gdb-python中宏的容器
我正在尝试访问内核链表,其结构是gdb-python中宏的容器,python,gdb,gdb-python,Python,Gdb,Gdb Python,我正在尝试访问内核链表,其结构是 struct my_struct { struct my_hardware_context ahw; struct net_device *netdev; struct pci_dev *pdev; struct list_head mac_list; struct list_head wait_list; .... .... }) 使用gdb,我可以按以下方式打印: (gdb)p*(qlcnic_wait_event_t*)((struct my_struc
struct my_struct {
struct my_hardware_context ahw;
struct net_device *netdev;
struct pci_dev *pdev;
struct list_head mac_list;
struct list_head wait_list;
....
....
})
使用gdb,我可以按以下方式打印:
(gdb)p*(qlcnic_wait_event_t*)((struct my_struct*)dev_base->next->priv.wait_list)
输出为:
$17 = {
list = {
next = 0x410026a14ff0,
prev = 0x410026a14ff0
},
comp_id = 0x0,
trigger = 0x0,
active = 0x0,
rsp_word = 0x0 <buses_init at vmkdrivers/src_9/vmklinux_9/linux/drivers/base/bus.c:1061>
执行(gdb)源容器\u of.py后
输出为:
wait_list = {
list = {
next = 0x410026a14ff0,
prev = 0x410026a14ff0
},
comp_id = 0x0,
trigger = 0x0,
active = 0x0,
rsp_word = 0x0 <buses_init at /src_9/linux_9/drivers/base/bus.c:1061>
}
ptr = 0x410026a14ff0
Traceback (most recent call last):
File "container_of.py", line 64, in ?
next = container_of(ptr,"struct qlcnic_wait_event_s","list")
File "container_of.py", line 23, in container_of
return (ptr.cast(get_long_type()) - offset_of(typeobj, member)).cast(typeobj)
File "container_of.py", line 19, in offset_of
element = gdb.Value(0).cast(typeobj)
RuntimeError: Argument must be a type.
等待列表={
列表={
next=0x410026a14ff0,
prev=0x410026a14ff0
},
组件id=0x0,
触发器=0x0,
活动=0x0,
rsp_字=0x0
}
ptr=0x410026a14ff0
回溯(最近一次呼叫最后一次):
文件“container_of.py”,第64行,在?
next=容器(ptr,“结构qlcnic等待事件”,“列表”)
文件“container_of.py”,第23行,在container_of.py中
return(ptr.cast(get_long_type())-offset_of(typeobj,member)).cast(typeobj)
文件“container_of.py”,第19行,偏移量为
元素=gdb.Value(0).cast(typeobj)
RuntimeError:参数必须是类型。
为什么它不起作用?如何实现这个容器?您应该在代码中添加一些调试打印,看看出了什么问题。我第一次读的时候觉得还可以,但你可以很容易地看到“cast”的参数类型,在“offset_of”中打印出来 我觉得这句话很奇怪:
return int(str(element[field].address), 16)
看起来你可以这样做:
return int(element[field].address)
您应该提供一个指向计算容器类型的指针类型,并提供示例代码来说明这一想法
# container_of(p, type, field) = (type*) (p - offset_of(type, field)
# offset_of(type, field) = field.bitpos / 8
container_address = int(str(dev_pointer), 16) - field.bitpos / 8
container_pointer = gdb.Value(container_address).cast(container_type.pointer())
代码的问题是cast()在 这一点,不是字符串。调用gdb.lookup_type()将修复该部分 关于偏移量/集装箱数量:目前最方便的方式 要让它工作,就要使用gdb的宏工具。这只是因为更容易访问函数或命令
(gdb) macro define offsetof(_type, _memb) \
((long)(&((_type *)0)->_memb))
(gdb) macro define container_of(_ptr, _type, _memb) \
((_type *)((void *)(_ptr) - offsetof(_type, _memb)))
这可能会进入你的.gdbinit
(gdb) print offsetof(struct foo, bar)
...
要在Python中使用它,可以用同样的方法重新实现它
您已开始使用gdb.Type/Field和强制转换操作,或
只需再次依赖宏定义:
(gdb) python print gdb.parse_and_eval("offsetof(struct foo, bar)")
...
大家好,我正在等待您的答复…我尝试了
返回int(元素[field].address)
但得到了相同的错误:-(第element=gdb.Value(0).cast(typeobj)
行中的'offset_of'函数似乎有问题。但我无法确定确切的问题。。
(gdb) python print gdb.parse_and_eval("offsetof(struct foo, bar)")
...