x86_64 Ubuntu下AArch64裸机工具链GDB调试失败排查
在x86_64架构的Ubuntu主机上,使用aarch64-none-elf裸机工具链开发Arm64汇编程序,编译链接后用对应GDB调试时失败,报错Don't know how to run,但在原生Arm64-8A设备上调试正常。希望仅通过x86主机的工具链完成调试,不想使用QEMU或连接实体设备,怀疑需添加链接参数。改用aarch64-none-linux-gnu工具链时仍出现相同错误。
疑问:
- 是否必须通过gdbserver连接原生Arm设备才能让GDB正常工作?
aarch64-none-linux-gnu工具链是否依赖原生设备,还是仅需配置调整?
核心结论
x86主机无法直接运行Arm64架构的二进制程序,交叉GDB本身没有指令模拟能力,因此必须依赖Arm64执行环境才能调试——要么用QEMU模拟Arm64环境,要么用实体Arm设备+gdbserver。仅靠交叉工具链本身无法完成调试。
针对疑问的详细说明
是否必须用gdbserver连接实体设备?
不是必须,QEMU是更便捷的替代方案:它能在x86主机上模拟Arm64的用户态或系统态环境,GDB可以通过远程调试协议连接QEMU的调试端口,实现完全在x86主机上的调试工作流。aarch64-none-linux-gnu工具链是否依赖实体设备?
不依赖实体设备,但它生成的是Arm64 Linux用户态可执行文件,需要在Arm64 Linux环境中运行——这个环境可以是QEMU用户态模拟,无需实体机。
为什么当前GDB调试失败?
交叉GDB(如aarch64-none-elf-gdb)只是调试器,没有运行非本机架构代码的能力。你直接加载target exec后,x86主机无法执行Arm64二进制,因此GDB无法启动程序,才会报错Don't know how to run。
另外,当前编译过程没有生成调试符号:需要在汇编阶段添加-g参数,而不是仅在链接阶段加,这样GDB才能识别调试信息。
具体调试步骤
1. 裸机程序(aarch64-none-elf)调试
- 重新编译,生成带调试符号的程序
aarch64-none-elf-as -g -o str11.o str11.s aarch64-none-elf-ld -g -o str11 str11.o
- 用QEMU系统态模拟裸机环境并开启调试端口(
-s表示监听1234端口,-S表示启动后暂停)
qemu-system-aarch64 -machine virt -cpu cortex-a53 -kernel str11 -s -S
- 启动GDB并连接QEMU
aarch64-none-elf-gdb str11 # 在GDB中执行以下命令 (gdb) target remote localhost:1234 (gdb) break _start (gdb) continue
2. Linux用户态程序(aarch64-none-linux-gnu)调试
- 重新编译带调试符号的程序
aarch64-none-linux-gnu-as -g -o str11.o str11.s aarch64-none-linux-gnu-ld -g -o str11 str11.o
- 用QEMU用户态启动程序并开启调试端口
qemu-aarch64 -g 1234 ./str11
- 启动GDB并连接
aarch64-none-linux-gnu-gdb str11 # 在GDB中执行以下命令 (gdb) target remote localhost:1234 (gdb) break _start (gdb) continue
内容的提问来源于stack exchange,提问作者TheMagmaCube

