用python解析gdb机器接口输出
pygdbmi的Python项目详细描述
pygdbmi-从gdb的机器接口获取结构化输出
文档https://cs01.github.io/pygdbmi
源代码https://github.com/cs01/pygdbmi
GDB/MI is a line based machine oriented text interface to GDB and is activated by specifying using the --interpreter command line option (see Mode Options). It is specifically intended to support the development of systems which use the debugger as just one small component of a larger system.
盒子里有什么?
- 一个解析gdb机器接口字符串输出并返回可序列化的结构化数据类型(python dict)的函数。用于将后端写入gdb前端。例如,gdbgui在后端使用pygdbmi。
- 一个python类,作为子进程控制gdb并与之交互
要从gdb获取machine interface输出,请使用--interpreter=mi2
标志运行gdb,如下所示:
gdb --interpreter=mi2
安装
pip install pygdbmi
兼容性
操作系统
对Linux、MacOS和Windows的跨平台支持
Linux/Unix
ubuntu 14.04和16.04已经过测试。其他版本也可能有效。
Mac操作系统
注意:错误
please check gdb is codesigned - see taskgated(8)
可以通过使用these instructions对gdb进行代码签名来修复。如果错误没有修复,请create an issue in github。窗口
windows 10已经过测试,可以与mingw和cygwin一起工作。
GDB版本
- gdb 7.6+已经过测试。旧版本也可以。
示例
gdb mi为其输出定义了一个语法,该语法适合于机器可读性和脚本:example output:
-> -break-insert main
<- ^done,bkpt={number="1",type="breakpoint",disp="keep",
enabled="y",addr="0x08048564",func="main",file="myprog.c",
fullname="/home/myprog.c",line="68",thread-groups=["i1"],
times="0"}
<- (gdb)
使用pygdbmi.gdbmiparser.parse_response
将该字符串输出转换为json可序列化字典
frompygdbmiimportgdbmiparserfrompprintimportpprintresponse=gdbmiparser.parse_response('^done,bkpt={number="1",type="breakpoint",disp="keep", enabled="y",addr="0x08048564",func="main",file="myprog.c",fullname="/home/myprog.c",line="68",thread-groups=["i1"],times="0"')pprint(response)>{'message':'done','payload':{'bkpt':{'addr':'0x08048564','disp':'keep','enabled':'y','file':'myprog.c','fullname':'/home/myprog.c','func':'main','line':'68','number':'1','thread-groups':['i1'],'times':'0','type':'breakpoint'}},'type':'result'}
对gdb的编程控制
但是,首先如何将gdb输出转换成python呢?如果需要,pygdbmi
还有一个类来控制gdb作为子进程。您可以编写命令,并获得结构化输出:
frompygdbmi.gdbcontrollerimportGdbControllerfrompprintimportpprint# Start gdb processgdbmi=GdbController()print(gdbmi.get_subprocess_cmd())# print actual command run as subprocess# Load binary a.out and get structured responseresponse=gdbmi.write('-file-exec-file a.out')pprint(response)[{'message':u'thread-group-added','payload':{u'id':u'i1'},'type':'notify'},{'message':u'done','payload':None,'type':'result'}]
现在用gdb做你想做的。所有gdb命令以及gdbmachine interface commands都可以接受。gdb mi命令提供了更好的结构化输出(机器可读),而不是gdb控制台输出。mi命令以-
开头。
response=gdbmi.write('-break-insert main')# machine interface (MI) commands start with a '-'response=gdbmi.write('break main')# normal gdb commands work too, but the return value is slightly differentresponse=gdbmi.write('-exec-run')response=gdbmi.write('run')response=gdbmi.write('-exec-next',timeout_sec=0.1)# the wait time can be modified from the default of 1 secondresponse=gdbmi.write('next')response=gdbmi.write('next',raise_error_on_timeout=False)response=gdbmi.write('next',raise_error_on_timeout=True,timeout_sec=0.01)response=gdbmi.write('-exec-continue')response=gdbmi.send_signal_to_gdb('SIGKILL')# name of signal is okayresponse=gdbmi.send_signal_to_gdb(2)# value of signal is okay tooresponse=gdbmi.interrupt_gdb()# sends SIGINT to gdbresponse=gdbmi.write('continue')response=gdbmi.exit()
分析输出格式
每个解析的gdb响应都包含一个字典列表。每个字典都有键message
、payload
、token
和type
。
message
包含来自gdb的文本消息,该消息并不总是存在的。如果丢失,这是None
。payload
包含gdb输出的内容,它可以包含以下任何内容:dictionary
、list
、string
。这也不总是存在的,并且可以是None
,这取决于响应。token
如果输入命令的前缀是(可选)标记,则该命令的相应输出也将以该标记为前缀。此字段仅适用于pygdbmi输出类型nofity
和result
。如果丢失,这是None
。
type
是基于gdb的各种mi output record types定义的,可以是
result
-gdb命令的结果,例如done
、running
、error
等。notify
-已发生的其他异步更改,例如修改了断点console
-对cli命令的文本响应log
-调试来自gdb内部的消息output
-目标输出target
-来自远程目标的输出done
-当gdb完成输出时
贡献
欢迎使用文档修复、错误修复、性能改进和功能改进。您可能希望在开始工作之前创建一个问题,以确保我有兴趣将其合并到主分支。
要进行开发,请设置一个新的虚拟环境,然后克隆此repo并运行pip install -e .[dev]
。
确认单元测试正在使用make test
,然后开始开发。
根据需要在pygdbmi/tests/test_app.py
更新单元测试。
使用pygdbmi的项目
- gdbgui实现基于浏览器的gdb前端,在后端使用pygdbmi
- PINCE是一个gdb前端,旨在提供一个反向工程工具和一个专注于游戏的可重用库。它使用pygdbmi解析某些函数基于gdb/mi的输出
- avatar²是一个用于反转和分析嵌入式设备固件的编排框架。它利用pygdbmi与不同的分析目标进行内部通信。
- 知道另一个项目吗?创建一个公关,并添加到这里。
作者
pygdbmi
是由Chad Smith和contributions from the community一起写的,作者对此非常感激。尤其要感谢@Mariusmue,@Bobthekingoffegypt,@Mouff和@Felipesere。