Самый простой способ получить вывод 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
Это не слишком сложно для анализа, но пока выиспользуя расширения Python для GDB, вы можете использовать метод 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
или команду gdb disassemble
;просто используйте числовые аргументы.