如何从qemu-system-i386获取含寄存器、内存信息的完整指令日志?
从QEMU-system-i386获取指令执行完整日志的方案
一、不使用GDB的方案
1. 基础指令与寄存器日志(覆盖需求1、2)
直接用QEMU内置调试参数开启单步执行与详细日志:
qemu-system-i386 -singlestep -d exec,cpu,in_asm -logfile qemu_exec.log
参数说明:
-singlestep:强制每条指令执行后暂停,确保日志无遗漏-d exec:打印每条指令的虚拟地址与反汇编内容-d cpu:输出指令执行前后的所有CPU寄存器状态-d in_asm:反汇编CS:EIP指向的指令及后续字节(覆盖32字节范围)-logfile:将日志写入文件,避免终端输出混乱
2. 内存访问追踪(覆盖需求3)
结合QEMU的trace事件系统,记录所有内存读写的线性地址、旧值与新值:
qemu-system-i386 -singlestep -d exec,cpu,in_asm -trace memory_read,memory_write -logfile qemu_full.log
-trace memory_read,memory_write:触发内存读写事件时,自动记录访问的线性地址、数据长度、读写值(读操作记录当前值,写操作记录旧值与新值)
3. 精准32字节内存转储(补充需求2)
若需要精准获取CS:EIP处的32字节内存,可通过QEMU Monitor自动化实现:
- 启动QEMU时开启Monitor交互端口:
qemu-system-i386 -singlestep -d exec,cpu -monitor telnet:localhost:5555,server,nowait -logfile qemu_base.log - 用Python/Expect脚本连接
localhost:5555,每次单步执行前发送命令x/32bx $cs:$eip,将内存转储结果追加到日志。
二、使用GDB的方案(兼容偶发问题优化)
1. 启动QEMU与GDB连接
# 启动QEMU并开启GDB服务器,暂停等待连接 qemu-system-i386 -s -S
# 启动i386架构GDB,连接QEMU target remote localhost:1234 # 开启日志记录 set logging on exec_trace.log
2. 自定义单步追踪脚本
在GDB中定义批量追踪命令,覆盖所有需求:
define full-trace # 记录执行前寄存器 info registers # 转储CS:EIP处32字节内存 x/32bx $cs:$eip # 反汇编当前及后续指令 disas $eip, $eip+32 # 执行单步指令 stepi # 记录执行后寄存器 info registers # 查看内存变更(需提前设置watchpoint,或用info breakpoints查看触发的内存断点) end
执行full-trace即可完成单步追踪,循环执行直到发现代码分歧。
3. GDB问题优化
- 反汇编错误:强制指定指令模式,
set disassembly-flavor intel(或att) - 偶发崩溃:减少单次追踪指令数量,分段记录日志,逐步缩小分歧范围
诊断代码分歧实用技巧
- 定位代码成功执行后的起始地址,设置断点跳过无问题代码段
- 对比正常与异常执行日志,重点关注寄存器突变、内存读写异常的位置
- 优先追踪分支指令(jmp、call、ret)的执行结果,快速定位分歧点
内容的提问来源于stack exchange,提问作者pts
相关产品推荐
相关产品推荐

