我需要做类似的事情,并遇到了两种方法:
- 在 GDB 中运行 Python,使用命令的 Python 脚本
- 对 GDB 使用 Python API,例如 pygdbmi
后者最终变得更加灵活,因此我将在此处解释这些步骤。
使用调试信息配置 qemu:
./configure --enable-debug
构建 qemu 并使用调试钩子暂停调用它:
make
sudo make install
qemu-system-x86_64 -S -s
现在,使用 Python 脚本通过 pygdbmi(instructions here) 附加到 qemu 并与之交互:
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' 命令在 localhost:1234 添加 GDB 挂钩。所以你发出的第一个命令必须让 gdb 去那里看:
gdbmi.write('target remote localhost:1234');