1

设置:GDB 使用脚本运行内部 python 解释器。脚本的内容disas在一些内存上运行。

我需要这个命令在 python 字符串中的输出。我怎样才能做到这一点?

想过记录,结果发现只记录了命令的第一行:

Dump of assembler code from 0x8000 to 0x8030:

disas 的预期结果在屏幕上,但不在日志文件中。

0x00008000: fsw fa0,24(a5)
0x00008002: fsd fs6,16(sp)
0x00008004: addi    s1,sp,920
...

是否可以将标准输出重定向到流中或以其他方式获取信息?

编辑:我已将 GDB 连接到 openOCD 服务器。我的目标是汇编程序命令。没有elf文件等等,我从中获取源代码。它只是驻留在控制器程序内存中的纯机器指令,我需要将其打印出来。

4

1 回答 1

1

将输出disassemble转换为字符串的最简单方法是给出gdb.execute一个to_string=True参数。

(gdb) start
...
(gdb) pi
>>> import pprint
>>> pp=pprint.PrettyPrinter()
>>> pp.pprint(gdb.execute("disassemble main",to_string=True))
('Dump of assembler code for function main:\n'
 '   0x00005555555546a4 <+0>:\tpush   %rbp\n'
 '   0x00005555555546a5 <+1>:\tmov    %rsp,%rbp\n'
 '=> 0x00005555555546a8 <+4>:\tcallq  0x555555554560 <pause@plt>\n'
 '   0x00005555555546ad <+9>:\tmov    $0x0,%eax\n'
 '   0x00005555555546b2 <+14>:\tpop    %rbp\n'
 '   0x00005555555546b3 <+15>:\tretq   \n'
 'End of assembler dump.\n')
>>> 

(我在这里使用 pprint 以便它在终端会话中很好地显示。)

您可以将其写入文件:

>>> with open("logfile","w") as log:
...   log.write(gdb.execute("disassemble main",to_string=True))
... 
335

解析这个并不难,但只要您使用 gdb 的 python 扩展,您可能想要使用该gdb.Architecture.disassemble方法,它为您完成大部分工作:

>>> frame=gdb.selected_frame()
>>> hex(frame.block().start)
'0x5555555546a4'
>>> hex(frame.block().end) # doc says this is "one past the last address that appears in the block"
'0x5555555546b4'
>>> arch=frame.architecture()
>>> arch.name()
'i386:x86-64'
>>> pp.pprint(arch.disassemble(frame.block().start, frame.block().end - 1))
[{'addr': 93824992233124, 'asm': 'push   %rbp', 'length': 1},
 {'addr': 93824992233125, 'asm': 'mov    %rsp,%rbp', 'length': 3},
 {'addr': 93824992233128, 'asm': 'callq  0x555555554560 <pause@plt>', 'length': 5},
 {'addr': 93824992233133, 'asm': 'mov    $0x0,%eax', 'length': 5},
 {'addr': 93824992233138, 'asm': 'pop    %rbp', 'length': 1},
 {'addr': 93824992233139, 'asm': 'retq   ', 'length': 1}]
>>>

如果您的程序没有调试信息,frame.block()将失败并显示RuntimeError: Cannot locate block for frame.. 还是可以成功调用arch.disassemble或者gdbdisassemble命令;只需使用数字参数。

于 2019-04-12T20:57:58.443 回答