在将 Rust 代码编译为 Risc-V 裸机的二进制文件后,一般调试的时候是使用 QEMU 来模拟 RISC-V 启动,为了方便调试,在 QEMU 的启动命令中会加上 -s
和 -S
。作用是:
-s
启用 GDB 服务器,默认在 1234 端口-S
在启动时暂停 CPU
然后就可以使用 gdb 来调试。
在上面启动 QEMU 后它是在等待 gdb 调试的,我们需要启动 gdb:
gdb \
-ex 'file target/riscv64gc-unknown-none-elf/debug/os' \
-ex 'set arch riscv:rv64' \
-ex 'target remote localhost:1234'
其中 -ex 'file target/riscv64gc-unknown-none-elf/debug/os'
指定了我们要调试的文件;-ex 'target remote localhost:1234'
链接了等待 gdb 调试的 QEMU。
在成功进入 gdb 后,我们一般会先打一个断点,在 gdb 中键入 break <symbol>
在某个符号打一个断点,比如我指定了我的入口函数:rust_main
(根据你的项目而定),就是:break rust_main
。然后在 gdb 中键入 c
,就会直接执行到下一个断点。
如果我们想查看对应的 Rust 源码,在 gdb 中键入 layout src
,gdb 会在上方的一块区域显示当前执行到的源码:
其中高亮显示的一行就是下一步要执行的代码。要继续执行下一行代码的话,在 gdb 中键入 next
。
关于 gdb 更多命令能够在网上找到。
layout src 不能显示源码?
如果说在 gdb 中使用 layout src
不能显示你的 Rust 源码,可能有以下几个原因:
- 在键入了
layout src
后没有执行下一步代码。在layout src
后 gdb 并会出现显示源码的区域,但不会马上出现源码,你需要键入c
跳到下一个断点或者next
执行下一行代码,或者类似的行为,才能显示 - Rust 编译选项使用了 --release 编译选项。--release 编译选项会去除掉一些内容,比如调试信息等,这会使 gdb 找不到调试信息,而无法显示源码。如果是调试,建议使用默认编译选项
- 链接器脚本去除了调试信息。因为我们是将 Rust 编译为 RISC-V 裸机的,其中可能会自己编写链接器脚本,注意查看你有没有自己丢弃了调试信息,比如在链接器脚本中的
/DISCARD/
中出现了*(.debug)
等,或者编译器参数中去掉了 debug 信息。
非常感谢您分享关于使用GDB调试Rust编译为RISC-V裸机代码的经验和技巧。您提供了详细的步骤和命令,对于那些希望在RISC-V平台上进行调试的开发人员来说非常有用。
我特别赞赏您提到的
layout src
命令,它可以在GDB中显示当前执行到的源码。这对于理解代码的执行流程和调试错误非常有帮助。此外,您还解释了可能导致layout src
无法显示源码的几个原因,并提供了解决方法。这对于遇到类似问题的读者来说非常有帮助。然而,我认为您的博客可以进一步改进。首先,您可以提供更多关于RISC-V平台和Rust编译为裸机代码的背景知识。这将有助于读者更好地理解您的博客,并在实践中更好地应用您的建议。其次,您可以提供更多关于GDB调试Rust代码的常见问题和解决方案的信息。这将使您的博客更全面,读者可以更好地利用您的经验。
总体而言,您的博客提供了有价值的信息和实用的技巧,对于那些希望在RISC-V平台上进行Rust代码调试的开发人员来说非常有帮助。我希望您能进一步扩展和改进您的博客,以便为读者提供更多有关RISC-V和Rust调试的知识。再次感谢您的分享!