保姆级教程:在Ubuntu上配置GDB远程调试QEMU里的ARM程序(含完整命令)

张开发
2026/4/3 20:34:58 15 分钟阅读
保姆级教程:在Ubuntu上配置GDB远程调试QEMU里的ARM程序(含完整命令)
从零构建ARM虚拟调试环境UbuntuGDBQEMU实战指南当你第一次尝试在x86电脑上调试ARM架构的程序时是否遇到过这样的困惑为什么本地GDB无法识别ARM指令如何让调试器与模拟器通信本文将带你用最经济的方式——无需开发板仅需普通PC就能搭建完整的ARM程序调试环境。1. 环境准备工具链与依赖项在开始之前我们需要准备三个核心工具交叉编译器、QEMU模拟器和多架构GDB。不同于常见的开发环境配置ARM调试需要特别注意工具版本间的兼容性。1.1 安装必备软件包打开终端执行以下命令一键安装所有依赖sudo apt update sudo apt install -y \ gcc-arm-linux-gnueabi \ gdb-multiarch \ qemu-system-arm \ make常见问题排查若遇到Unable to locate package错误尝试先运行sudo apt updateUbuntu 22.04用户可能需要将gcc-arm-linux-gnueabi替换为gcc-arm-linux-gnueabihf1.2 验证安装结果依次检查各工具是否可用arm-linux-gnueabi-gcc --version | head -n1 gdb-multiarch --version | head -n1 qemu-system-arm --version | head -n1正常输出应类似arm-linux-gnueabi-gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 GNU gdb (Ubuntu 12.1-3ubuntu1) 12.1 QEMU emulator version 6.2.0 (Debian 1:6.2dfsg-2ubuntu6.6)2. 创建测试项目从汇编开始理解ARM架构为了深入理解调试过程我们从一个最简单的ARM汇编程序开始。创建项目目录并新建两个文件2.1 编写测试程序start.S文件内容.text .global _start _start: mov r0, #42 将立即数42存入寄存器r0 add r1, r0, #100 r1 r0 100 loop: b loop 无限循环对应的MakefileCROSS_COMPILE ? arm-linux-gnueabi- CC : $(CROSS_COMPILE)gcc LD : $(CROSS_COMPILE)ld .PHONY: all clean all: test.elf test.elf: start.S $(CC) -nostdlib -g -o $ $ clean: rm -f test.elf关键编译参数说明-nostdlib不链接标准库-g生成调试信息-o test.elf输出可执行文件2.2 编译与验证执行编译命令make使用file命令验证生成的文件格式file test.elf正确输出应显示test.elf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped3. QEMU配置与GDB连接实战现在进入核心环节——配置模拟环境并建立调试会话。这个过程需要两个终端窗口协同工作。3.1 启动QEMU调试服务器在第一个终端执行qemu-system-arm \ -M vexpress-a9 \ -m 512M \ -kernel test.elf \ -S -s \ -nographic参数详解参数作用-M vexpress-a9模拟ARM vexpress-a9开发板-m 512M分配512MB内存-kernel test.elf加载我们的测试程序-S启动时暂停CPU执行-s开启GDB服务器并监听1234端口-nographic禁用图形界面输出3.2 连接GDB调试器在第二个终端启动GDBgdb-multiarch test.elf在GDB交互界面中输入target remote :1234 layout asm break _start continue此时你将看到左侧显示反汇编窗口程序停在_start标签处寄存器窗口显示当前CPU状态3.3 基础调试命令速查常用GDB命令参考命令功能示例info registers查看所有寄存器info registers r0stepi单步执行汇编指令stepix/10x $pc查看内存内容x/10x $spbreak *0x地址设置断点break *0x10000continue继续执行continue4. 高级调试技巧与故障排除掌握了基础调试方法后我们来处理一些实际开发中常见的问题场景。4.1 处理符号加载失败当GDB提示No symbol table is loaded时可以尝试确认编译时添加了-g参数在GDB中手动加载符号file test.elf symbol-file test.elf4.2 多线程调试配置如果调试多线程程序需要在QEMU启动时指定SMP核心数qemu-system-arm -M vexpress-a9 -smp 4 -m 512M -kernel test.elf -S -s在GDB中查看线程info threads thread 24.3 内存断点设置ARM架构支持硬件断点设置方法hbreak *0x10000 # 硬件断点 watch *(int*)0x20000000 # 监视内存写入4.4 性能优化技巧对于大型程序调试可以在QEMU启动时启用加速qemu-system-arm -enable-kvm -cpu host ...使用GDB的skip命令忽略不需要调试的库函数设置条件断点减少中断频率break foo.c:123 if x 425. 真实项目调试案例嵌入式RTOS应用让我们以一个实际场景结束本教程——调试运行在FreeRTOS上的应用程序。5.1 准备RTOS环境下载FreeRTOS源码git clone https://github.com/FreeRTOS/FreeRTOS.git编译示例项目cd FreeRTOS/FreeRTOS/Demo/CORTEX_A9_QEMU_GCC make5.2 启动调试会话QEMU端qemu-system-arm -M vexpress-a9 -m 512M -kernel build/rtos_demo.elf -S -sGDB端target remote :1234 break vTaskStartScheduler continue5.3 任务状态监控在GDB中查看任务列表p pxReadyTasksLists p xDelayedTaskList1使用FreeRTOS提供的GDB脚本增强调试source FreeRTOS/FreeRTOS/scripts/gdb/freertos_gdb.py info freertos tasks

更多文章