Мне нужно было сделать нечто подобное, и я натолкнулся на два подхода:
- Запустить Python в GDB, используя скрипт Python для команд
- Использовать API-интерфейс Python для GDB, какpygdbmi
Последнее оказалось более гибким, поэтому я объясню эти шаги здесь.Сконфигурируйте qemu с отладочной информацией:
./configure --enable-debug
Сборка qemu и его остановка с использованием отладочных хуков:
make
sudo make install
qemu-system-x86_64 -S -s
Теперь используйте скрипт Python для подключения к qemu и взаимодействия с ним через pygdbmi( инструкции здесь ):
from pygdbmi.gdbcontroller import GdbController
from pprint import pprint
# Start gdb process
gdbmi = GdbController()
print(gdbmi.get_subprocess_cmd()) # print actual command run as subprocess
gdbmi.write('target remote localhost:1234'); # attach to QEMU GDB socket
pprint(response)
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 different
response = 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 second
response = 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 okay
response = gdbmi.send_signal_to_gdb(2) # value of signal is okay too
response = gdbmi.interrupt_gdb() # sends SIGINT to gdb
response = gdbmi.write('si 20') # step 20 instructions
response = gdbmi.write('continue')
response = gdbmi.exit()
Если у вас возникли проблемы с символами ядра, вам также может потребоваться выполнить команду 'file myKernel', чтобы загрузить таблицу символов из этого файла, предполагая, чтоон был скомпилирован с отладочной информацией.
Для справки, команда '-s' добавляет ловушки GDB на localhost: 1234.Таким образом, первая команда, которую вы вводите, должна указать gdb:
gdbmi.write('target remote localhost:1234');