You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单终端内后台运行QEMU并连接GDB调试的实现方法

问题说明
  • 开发场景:卡内基梅隆大学计划明年发射的月球车项目ISIS OBC(星载计算机)飞控软件开发,需在预装全量兼容依赖的Docker容器内完成QEMU仿真+GDB调试,规避高版本GCC不兼容等环境问题
  • 现存问题:直接使用&将QEMU放入后台、或添加-daemonize参数启动时,QEMU的GDB监听服务会完全失效;原有依赖gnome-terminal新开窗口跑QEMU的方案,在无GUI的Docker容器内无法使用
  • 目标:单终端窗口内完成QEMU后台启动、GDB连接调试全流程,无需额外GUI终端
故障原因

QEMU配置了-serial stdio参数时会持续占用标准输入输出:

  1. 直接用&把QEMU丢后台时,后台进程没有当前tty的读写权限,会收到SIGTTIN信号被内核暂停,GDB服务自然无法正常监听
  2. -daemonize参数会让QEMU主动脱离当前会话、重定向所有文件描述符,很容易打断GDB stub的初始化流程,导致1234端口的监听服务不启动
可直接使用的修复方案

用命名管道(FIFO)给QEMU提供独立的输入通道,彻底解绑QEMU和当前终端tty的关联,不需要新开窗口,完全适配Docker无GUI环境。修改后的调试脚本如下:

#!/bin/bash
# 启动前先清理残留进程和临时文件
pkill -f iobc-loader 2>/dev/null || true
rm -f /tmp/qemu-out /tmp/qemu-in

# 创建命名管道作为QEMU的标准输入,避免后台进程读tty被暂停
mkfifo /tmp/qemu-in

# 后台启动QEMU,输入走命名管道,输出和错误都重定向到临时文件
./../obc-emulation-resources/obc-qemu/iobc-loader \
  -f sdram build/app.isis-obc-rtos.bin \
  -s sdram -o pmc-mclk \
  -- -serial stdio -monitor none -s -S \
  < /tmp/qemu-in > /tmp/qemu-out 2>&1 &
QEMU_PID=$!

# 后台实时打印QEMU输出到当前终端,不需要看QEMU串口输出可以删掉这两行
tail -f /tmp/qemu-out &
TAIL_PID=$!

# 等待QEMU完成GDB端口初始化,启动慢的环境可以把1改成2
sleep 1

# 启动GDB连接调试
./third_party/gcc-arm-none-eabi-10.3-2021.07/bin/arm-none-eabi-gdb \
  -ex='target remote localhost:1234' \
  -ex='symbol-file build/isis-obc-rtos.elf'

# GDB退出后自动清理所有进程和临时文件
kill $QEMU_PID $TAIL_PID 2>/dev/null || true
wait $QEMU_PID $TAIL_PID 2>/dev/null || true
rm -f /tmp/qemu-in /tmp/qemu-out
clear
注意事项
  • 不要给QEMU加-daemonize参数,这个参数的fork逻辑会干扰GDB服务启动
  • 如果不需要在当前终端看QEMU的串口输出,直接删掉tail -f相关的两行即可,所有输出会保存在/tmp/qemu-out里
  • 如果GDB启动时提示localhost:1234连接失败,把脚本里的sleep 1调大到2-3秒,等QEMU完全启动后再连就行

内容的提问来源于stack exchange,提问作者Henry Howland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:30:53