NEMU模拟器的gdb调试和指令调试
- 1 通过gdb调试NEMU
- 1.1 编译NEMU
- 1.2 gdb调试
- 2 通过NEMU调试指令
关于如何编译NEMU,以及编译MySBI+BenOS固件,运行等前置知识,可参考 《NEMU模拟器源码编译与使用》。
1 通过gdb调试NEMU
1.1 编译NEMU
当我使用make riscv64-xs_defconfig
时,可以正常gdb调试,无问题。
但是,如果使用make riscv64-benos_defconfig
的话,编译NEMU源码时,就会报错,可能是这个配置的关系。
编译,附带调试信息的NEMU,步骤:
apt install build-essential man gcc gdb git libreadline-dev libsdl2-dev zstd libzstd-dev
git clone https://github.com/OpenXiangShan/NEMU.git
cd NEMU/
export NEMU_HOME=/home/test/NEMU # /home/test/NEMU换成自己NEMU源码目录
make riscv64-benos_defconfig # riscv64-benos_defconfig需放入NEMU/configs/
make menuconfig
配置以下选项,使其附带调试信息:
- Build Options -> Optimization Level:选择O0,表示编译器不优化
- Build Options -> Enable link-time optimization:取消选中,表示禁用链接时优化
- Build Options -> Enable debug information:选中,表示使能调试信息
保存,退出。
执行编译
make -j`nproc`
编译报一大堆错误,如下:
src/isa/riscv64/instr/decode.c: In function ‘table_csrrw’:
src/isa/riscv64/instr/decode.c:26:1: error: ‘%s’ directive output may be truncated writing up to 39 bytes into a region of size between 33 and 72 [-Werror=format-truncation=]def_all_THelper();^~~~~~~~~~~~~~~~~~
看了下,错误全是一样的。
原因: Makefile文件中,设置的编译等级比较高,使用-werror选项,导致如果出现任何警告都将视为错误,所以就会导致编译失败。
解决办法: 在Makefile中,将-werror删除,重新编译。
这里,我们删除NEMU/scripts/build.mk中,所有-Werror选项,如下所示:
CFLAGS := -O2 -MMD -Wall -Werror $(INCLUDES) $(CFLAGS)
CXXFLAGS := -O2 -MMD -Wall -Werror --std=c++17 $(XINCLUDES) $(CFLAGS)
再次编译,依旧一大堆警告,但是不报错,最后编译成功。
1.2 gdb调试
gdb调试NEMU:
cd NEMU/build/
gdb --args ./riscv64-nemu-interpreter -b benos_payload.bin # benos_payload.bin需放入NEMU/build/
gdb报错,如下:
dictionary.c:690: internal-error: void insert_symbol_hashed(dictionary*,
symbol*): Assertion `SYMBOL_LANGUAGE (sym) == DICT_LANGUAGE
(dict)->la_language' failed.
报错原因: 这是gdb的一个bug,可参考:https://sourceware.org/bugzilla/show_bug.cgi?id=23999。
解决办法: 升级gdb。我这里从gdb8.1.1,升级到gdb10.2后,解决此问题。
升级gdb10.2,步骤如下:
# 下载GDB源代码
wget http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz
# 解压缩
tar -xzf gdb-10.2.tar.gz
# 进入目录
cd gdb-10.2/
# 配置安装
./configure
make -j`nproc`
# 安装到系统路径
sudo make install
默认安装到/usr/local/bin目录下,将该目录加入环境变量:
vim ~/.bashrc
export PATH=/usr/local/bin:$PATH # 在文件的末尾添加本行
source ~/.bashrc
查看版本gdb -v
再次调试NEMU,可以在nemu-main.c:24打断点,如下:
输入r
运行,可以在nemu-main.c:24处停住,然后按Ctrl+Alt+A
,显示如下:
gdb调试NEMU成功。
2 通过NEMU调试指令
NEMU中运行benos_payload.bin,可通过如下命令,调试指令:
./riscv64-nemu-interpreter benos_payload.bin
注意:不带-b选项
进入NEMU调试界面,如下:
si
命令,表示单步执行。
我们可以继续单步,就可以从benos_payload.bin中,第一条指令,依次往下执行了。
每一步会显示出机器码和对应汇编。