Сценарии Python
Это даст большую гибкость, чем сценарии GDB, для реализации ваших безумных идей.
Основная проблема, как и в случае сценариев GDB, заключается в том, чтоэто, вероятно, будет слишком медленным для большинства приложений без поддержки целевого оборудования, например: мир приветствия C занимает 1 минуту только для 18k инструкций.
gdb.py
class TraceAsm(gdb.Command):
def __init__(self):
super().__init__(
'trace-asm',
gdb.COMMAND_BREAKPOINTS,
gdb.COMPLETE_NONE,
False
)
def invoke(self, argument, from_tty):
argv = gdb.string_to_argv(argument)
if argv:
gdb.write('Does not take any arguments.\n')
else:
done = False
thread = gdb.inferiors()[0].threads()[0]
last_path = None
last_line = None
with open('trace.tmp', 'w') as f:
while thread.is_valid():
frame = gdb.selected_frame()
sal = frame.find_sal()
symtab = sal.symtab
if symtab:
path = symtab.fullname()
line = sal.line
else:
path = None
line = None
if path != last_path:
f.write("path {}{}".format(path, os.linesep))
last_path = path
if line != last_line:
f.write("line {}{}".format(line, os.linesep))
last_line = line
pc = frame.pc()
f.write("{} {} {}".format(hex(pc), frame.architecture().disassemble(pc)[0]['asm'], os.linesep))
gdb.execute('si', to_string=True)
TraceAsm()
GitHubupstream .
main.S
global _start
_start:
; Write.
mov rax, 1
mov rdi, 1
mov rsi, hello_world
mov rdx, hello_world_len
syscall
; Exit.
mov rax, 60
mov rdi, 0
syscall
hello_world db "hello world", 10
hello_world_len equ $ - hello_world
GitHub upstream .
Сборка и запуск:
as -o main.o main.S
ld -o main.out main.o
gdb -nh -batch -ex 'source ~/test/gdb.py' -ex 'starti' -ex 'trace-asm' ./main.out
cat trace.tmp
Вывод:
0x401000 mov $0x1,%rax
0x401007 mov $0x1,%rdi
0x40100e mov $0x402000,%rsi
0x401015 mov $0xc,%rdx
0x40101c syscall
0x40101e mov $0x3c,%rax
0x401025 mov $0x0,%rdi
0x40102c syscall
Эмуляция QEMU
Это выполняется намного быстрее, чем решение GDB Python, C hello работает мгновенно!Однако в журнале было всего 10 тыс. Инструкций вместо 18 тыс. В одном и том же исполняемом файле, поэтому он должен пропускать то, что обычно запускается при запуске TODO.
Например, при моделировании в пользовательском режиме:
qemu-x86_64 -d in_asm ./main.out
Вывод:
warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
----------------
IN:
0x0000000000401000: mov $0x1,%rax
0x0000000000401007: mov $0x1,%rdi
0x000000000040100e: mov $0x402000,%rsi
0x0000000000401015: mov $0xc,%rdx
0x000000000040101c: syscall
hello world
----------------
IN:
0x000000000040101e: mov $0x3c,%rax
0x0000000000401025: mov $0x0,%rdi
0x000000000040102c: syscall
См. Также .
Проверено в Ubuntu 18.10, GDB 8.2, QEMU 2.12.0.