我正在编写一个python脚本来自动调试来自gdb的核心转储.我正在尝试打印包含内核数据结构和列表的数据结构(例如struct list_head).例如,结构是这样的:
struct my_struct {
struct my_hardware_context ahw;
struct net_device *netdev;
struct pci_dev *pdev;
struct list_head mac_list;
....
....
};
Run Code Online (Sandbox Code Playgroud)
我使用以下API tp打印此结构:
gdb.execute('p(*(struct my_struct*)dev_base-> priv)')
所以我能够自动打印'struct my_struct',struct my_hardware_context ahw的内容,但不能打印指针和列表的内容(例如struct net_device*netdev,struct pci_dev*pdev,struct list_head mac_list)(只打印地址).那么如何使用gdb-python脚本打印*netdev,*pdev和mac_list的内容?
编辑:使我的问题更清楚
我正在编写一个python脚本来自动调试来自gdb的核心转储.我正在尝试打印包含内核数据结构和列表的数据结构(例如struct list_head).例如,结构是这样的:
struct my_struct {
struct my_hardware_context ahw;
struct net_device *netdev;
struct pci_dev *pdev;
struct list_head mac_list;
....
....
};
Run Code Online (Sandbox Code Playgroud)
我正在使用以下API来打印此结构:(可以假设我有正确的核心转储并添加了正确的符号.
main_struct = gdb.execute('p (*(struct my_struct *)dev_base->priv)')
print main_struct
现在它将打印struct my_struct的所有成员的值,但最多可以打印一个级别,这意味着它将打印struct my_hardware_context ahw的全部内容,因为它是一个实例,但它不会打印struct net_device*netdev,struct pci_dev*pdev的内容,struct list_head mac_list等所以现在手动我需要像下面这样做:
netdev = gdb.parse_and_eval('*(*(struct my_struct *)dev_base->next->priv).netdev')
print netdev
pdev = …
我使用的是 RHEL 5.3 操作系统、gdb7.5 和python2.7。我正在用 Python 编写一个脚本来自动化一些 gdb 调试步骤。我们可以将以下命令(“name1”)的输出存储到一个变量中吗?
(gdb) p *(ptr->name)
$13 = "name1"
Run Code Online (Sandbox Code Playgroud)
我想这样做是因为在我的 Python 脚本中,我会将这个 ( name1) 与用户输入字符串进行比较,如果匹配,将执行一些操作,否则要求用户输入另一个字符串。
如果不可能,请建议我替代。
我正在尝试访问内核链表,结构是
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;
....
....
Run Code Online (Sandbox Code Playgroud)
};
使用 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>
Run Code Online (Sandbox Code Playgroud)
}
要迭代列表,我需要转到“下一步”wait_list并使用“container_of”,获取地址的基址。所以我使用 container_of 宏,代码是
#!/usr/bin/env python
import gdb
long_type = None
def get_type(type_name):
t = gdb.lookup_type(type_name)
if t == None: …Run Code Online (Sandbox Code Playgroud) 我正在调试C程序时使用python2.6的gdb模块,并希望根据实例的'.Type'将gdb.Value实例转换为python数字对象(变量).
例如,将我的C程序SomeStruct->some_float_val = 1./6;转换为Python gdb.Value sfv=gdb.parse_and_eval('SomeStruct->some_double_val'),但是然后把它变成一个双精度浮点python变量 - 知道str(sfv.type.strip_typedefs())=='double'它的大小是8B - 没有用转换字符串dbl=float(str(sfv))或者Value.string()更像是解压缩bytes struct用于获取正确的double值.
从我的搜索点返回的每个链接https://sourceware.org/gdb/onlinedocs/gdb/Values-From-Inferior.html#Values-From-Inferior,但我看不到如何将Value实例转换为python变量干净,比如说Value在C内存中都不是,但是代表了一个gdb.Value.address(所以不能使用Inferior.read_memory()),怎么会把它变成Python int而没有转换字符串值?
我想将一些命令行参数传递给通过gdb命令运行的 python 脚本,但是在 python 中导入 gdb 模块会从 sys.path 中删除 argv 属性。如何在示例中显示的 python 脚本中访问 arg1 和 arg2?
$ gdb -x a.py --args python -arg1 -arg2
Run Code Online (Sandbox Code Playgroud)
#!/usr/bin/env python
import gdb
import sys
print('The args are: {0}'.format(sys.argv))
gdb.execute('quit')
Run Code Online (Sandbox Code Playgroud)
AttributeError: 'module' object has no attribute 'argv'
Run Code Online (Sandbox Code Playgroud)
我要调试的最终目标是一个已经在运行的 C 可执行文件,所以我稍后会在脚本中附加到它,所以gdb -x a.py --args python -arg1 -arg2也不正确,因为该python部分打印了一个 gdb 错误:Reading symbols from /usr/bin/python...(no debugging symbols found)...done....
我想在崩溃发生之前检查一些全局变量。该问题仅在特定的堆栈跟踪中重现,并且在最内层函数(或堆栈中的任何其他函数)上设置断点将无法使我足够接近。
仅当堆栈顶部包含类似内容时,我才能达到中断的结果吗?
#0 __GI_connect
#1 curl_connect
#2 get_file
#3 init_assets
Run Code Online (Sandbox Code Playgroud)
只是做
b init_assets
c
b get_file
c
...
Run Code Online (Sandbox Code Playgroud)
由于多次调用init_assets且不会每次都调用curl,因此无法正常工作,因此gdb会中断使用curl的无关代码。
以后编辑:另一种方法是:
b inner_func
ignore 1 10000
r
# app crashes
info b
Breakpoint 1 has been hit 10 times.
Run Code Online (Sandbox Code Playgroud)
然后删除断点,将其重新添加,仅忽略9次。再次运行该应用程序时,gdb将在第10次停止-当inner_func崩溃时。
rr如果执行差异太大,您也可以将应用程序记录在mozilla中。