没有开发板也能调试 ARM64 程序QEMU GDB 远程调试实战上一篇我们在 Ubuntu 20.04 上用 Buildroot 和 QEMU 启动了 ARM64 Linux并运行了交叉编译的 Hello World。这一次不只看程序的输出而是停在函数入口检查参数、数组和调用栈并进一步练习单步执行。即使没有实体开发板也可以先练习嵌入式 Linux 用户态程序的远程调试。实测范围使用 Buildroot 交叉 GDB 15.2 和目标端 gdbserver 15.2已验证连接、命中断点、变量检查、调用栈、最终输出和正常退出并记录了旧 GDB 客户端的兼容性问题。单步执行作为延伸练习尚未实测文中相关结果仅为预期。Ubuntu 20.04 已结束标准维护继续联网使用时应确认适用的安全维护方案。一、这次要完成什么我们将运行一个计算数组总和的 ARM64 程序在 Ubuntu 上通过 GDB设置断点停在计算函数入口查看参数和数组查看调用栈确认函数由哪里调用继续执行观察最终输出完成上述已实测流程后还可以按第十节的延伸练习单步执行、观察局部变量。该部分尚未实测不计入本文已验证结果。预期在 GDB 中看到类似结果行号以实际源码为准Breakpoint 1, compute_total (...) at debug_demo.c:... (gdb) print count $1 4 (gdb) print values[0] $2 10二、先分清两种调试方式方式连接对象本文是否使用Linux 中的gdbserver某个用户态进程是调试我们的 C 程序QEMU 的-s/-gdb接口模拟 CPU可用于内核等调试否不是本篇的用户态进程调试路径本文的链路是Ubuntu x86_64Buildroot 交叉 GDB持有源码和未剥离符号的程序 │ TCP 127.0.0.1:5000 ▼ QEMU 用户网络端口转发 │ 客体 TCP 2345 ▼ ARM64 Buildroot Linuxgdbserver → /root/debug_demoUbuntu 中的127.0.0.1与 QEMU 客体中的回环地址不是同一个地址。端口转发把两端连接起来不需要桥接、TAP 或实体开发板。三、实验环境与前置条件项目本文约定Ubuntu 构建主机Ubuntu 20.04 x86_64可运行在 VirtualBox 中Buildroot 源码目录~/buildroot-2025.02.8目标平台qemu_aarch64_virt_defconfigAArch64 Linux现有产物output/images/Image、output/images/rootfs.ext2交叉编译器当前 Buildroot 生成的工具链QEMU 程序Ubuntu 的/usr/bin/qemu-system-aarch64版本按第七节命令记录GDB 客户端Buildroot 构建的交叉 GDB 15.2运行在 Ubuntu 上GDB 服务端Buildroot 构建的 AArch64gdbserver15.2开始前确认上一篇的系统能够启动并在 QEMU 中执行uname -m得到aarch64。本次最初尝试了 Ubuntu 系统的gdb-multiarch 9.2后来遇到兼容性问题改用 Buildroot 交叉 GDB 15.2。下面保留最初的安装记录用于说明第九节的排错背景直接复现成功流程时无需安装旧客户端按第九节构建交叉 GDB 即可sudoaptupdatesudoaptinstall-ygdb-multiarch gdb-multiarch--version最初尝试的系统客户端版本输出如下省略许可证说明embedembedtest:~$ gdb-multiarch --version GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.2) 9.2该输出只确认旧客户端安装成功不代表它与本次目标环境兼容。后文的成功验证使用交叉 GDB 15.2 与 gdbserver 15.2客户端与服务端不一定必须版本相同但不能仅凭版本相近判断兼容性应以实际连接和调试结果为准。四、在 Buildroot 中启用 gdbserver1. 备份现有配置并打开菜单先正常关闭使用当前 rootfs 镜像的 QEMU然后在 Ubuntu 的终端中执行不是在 Buildroot 客体的#提示符中执行cd~/buildroot-2025.02.8cp.config$HOME/buildroot-config-before-gdb-$(date%Y%m%d-%H%M%S).bakmakemenuconfig备份命令只保存当前.config不会修改配置。不要再次执行make qemu_aarch64_virt_defconfig否则可能覆盖之前的自定义设置。菜单使用键盘操作上下方向键移动Enter进入子菜单空格切换选项Tab切换底部按钮选择Exit后按Enter返回上一层。按/可以搜索配置符号搜索结果只显示位置和依赖不是可以直接勾选的配置页面。2. 先检查工具链的 C 支持从主菜单进入Toolchain找到Enable C support。若尚未启用按空格使其显示为[*] Enable C support本次原配置未启用 C调试软件菜单中因此只显示以下依赖提示没有可选的 gdb 项*** gdb/gdbserver 8.x needs a toolchain w/ C, gcc 4.8 ***测试程序本身虽然用 C 编写但该版本的 GDB/gdbserver 构建需要工具链支持 C。Ubuntu 安装了g不代表 Buildroot 的 ARM64 工具链已启用 C这里需设置的是目标工具链的BR2_INSTALL_LIBSTDCPP。3. 启用目标端 gdbserver返回主菜单依次进入Target packages → Debugging, profiling and benchmark → gdb找到gdb后按空格启用再检查其下的gdbserver。本次菜单显示如下[*] gdb -*- gdbserver[*]表示选项已启用-*-表示选项已被依赖规则选中不能自由切换但同样是启用状态不需要再按空格。若你的菜单里gdbserver是[ ]则需要手动启用。若存在full debugger子选项本篇不需要启用它客户端调试由运行在 Ubuntu 上的 Buildroot 交叉 GDB 负责第九节单独配置构建。也可以按/搜索BR2_PACKAGE_GDB_SERVER根据结果定位菜单。若选项仍不可用检查搜索结果的依赖条件不要尝试修改搜索页面也不要随意更换目标架构。4. 保存并检查配置选择底部Exit逐级退出询问是否保存新配置时选择Yes。看到 Ubuntu 的embedembedtest:...$提示符后执行grep-E^BR2_(INSTALL_LIBSTDCPP|PACKAGE_GDB|PACKAGE_GDB_SERVER)y.config成功可以看到embedembedtest:~/buildroot-2025.02.8$ grep -E ^BR2_(INSTALL_LIBSTDCPP|PACKAGE_GDB|PACKAGE_GDB_SERVER)y .config BR2_INSTALL_LIBSTDCPPy BR2_PACKAGE_GDBy BR2_PACKAGE_GDB_SERVERy三项均为y才表示这一步配置已保存尚不代表 gdbserver 已经构建或安装进镜像。如果缺少某项重新进入make menuconfig检查。5. 工具链配置变更后完整重建如果本次将 C 支持从未启用改为启用这是工具链配置变更不能仅靠原有构建目录的增量编译保证一致性。应先备份旧镜像和修改后的配置再完整重建。若原工具链已经启用 C本次只增加 gdbserver则一般无需执行这里的make clean可按后续步骤增量构建。以下make clean会删除现有output/构建结果包括交叉工具链和系统镜像需要重新编译。默认位于源码目录下的dl/下载缓存和顶层.config会保留不要使用会移除配置的make distclean。确认 QEMU 已关闭、镜像未挂载且磁盘空间足够后再操作。先逐条完成备份任何命令失败就停止不要继续清理cd~/buildroot-2025.02.8BACKUP_DIR$HOME/buildroot-before-cxx-$(date%Y%m%d-%H%M%S)mkdir-p$BACKUP_DIRcp.config$BACKUP_DIR/config-with-gdbcp-aoutput/images$BACKUP_DIR/ls-lh$BACKUP_DIR/images/df-h.确认备份存在后执行完整重建不要使用sudo makemakecleanmake-j2echo$?make clean成功后才执行构建构建结束后立即执行echo $?返回0才继续下一节。已有源码缓存通常可以复用但新增的 GDB 依赖仍可能需要下载。重建后再使用新的 Buildroot 工具链编译测试程序第六节加入 overlay 后的make则用于更新镜像。五、准备带调试信息的 ARM64 程序以下命令都在 Ubuntu 主机的 Buildroot 源码目录执行不是在 QEMU 的#shell 中执行。创建源码cd~/buildroot-2025.02.8catdebug_demo.cEOF #include stdio.h int compute_total(const int *values, int count) { int total 0; for (int index 0; index count; index) { total values[index]; } return total; } int main(void) { const int values[] {10, 20, 30, 40}; int result compute_total(values, 4); printf(total %d\n, result); return 0; } EOF查找 Buildroot 编译器findoutput/host/bin-maxdepth1-nameaarch64-buildroot-linux-*-gcc-print将下面命令中的编译器路径替换为上一步的实际输出。本例沿用上一篇的 glibc 工具链。使用 Buildroot 自己生成的工具链可使测试程序的 ABI 和 C 库与目标 rootfs 保持一致。output/host/bin/aarch64-buildroot-linux-gnu-gcc\-Wall-Wextra-O0-g-gdwarf-4 -fno-omit-frame-pointer\debug_demo.c-odebug_demofiledebug_demo选项作用-O0关闭优化使入门时源码行、变量与执行过程更容易对应-g生成调试信息-gdwarf-4使用 DWARF 4降低新编译器默认调试格式与旧 GDB 不兼容的可能性-fno-omit-frame-pointer保留帧指针辅助调用栈分析不要对 Ubuntu 上准备交给 GDB 的debug_demo执行strip。它必须与部署到客体中的程序来自同一次编译只留下 ARM64 可执行文件、却丢掉调试符号会影响源码级调试。embedembedtest:~/buildroot-2025.02.8$ file debug_demo debug_demo: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 6.12.0, with debug_info, not stripped六、用 rootfs overlay 部署程序上一篇通过挂载生成镜像复制程序。这次使用 Buildroot 的 rootfs overlay让重新生成 rootfs 时自动包含测试程序。在 Ubuntu 中执行mkdir-prootfs-overlay/rootinstall-m0755 debug_demo rootfs-overlay/root/debug_demomakemenuconfig在System configuration中找到Root filesystem overlay directories填写/home/embed/buildroot-2025.02.8/rootfs-overlay路径按实际用户名调整。若该选项已有其他 overlay 路径应保留它们再追加本次目录不要覆盖原有设置。保存后检查grep^BR2_ROOTFS_OVERLAY.configmake-j2echo$?echo $?必须紧接make返回0才表示构建成功。构建会下载新增的 GDB 相关源码及依赖若遇到证书问题应配置可信 CA 或按前一篇方式准备下载缓存不要关闭证书或哈希校验。确认目标目录包含服务端和程序ls-loutput/target/usr/bin/gdbserverls-loutput/target/root/debug_demols-lhoutput/images/重新构建会生成新镜像之前仅通过挂载手动加入的/root/hello可能被覆盖。本篇将程序保存在 overlay 中源码修改后需要重新编译、更新 overlay 并再次构建镜像。本次 Buildroot 构建产物检查如下embedembedtest:~/buildroot-2025.02.8$ ls -l output/target/usr/bin/gdbserver -rwxr-xr-x 1 embed embed 638144 Oct 12 15:21 output/target/usr/bin/gdbserver embedembedtest:~/buildroot-2025.02.8$ ls -l output/target/root/debug_demo -rwxr-xr-x 1 embed embed 10696 Oct 12 15:19 output/target/root/debug_demo embedembedtest:~/buildroot-2025.02.8$ ls -lh output/images/ total 24M -rw-r--r-- 1 embed embed 12M Oct 12 14:59 Image -rw-r--r-- 1 embed embed 60M Oct 12 15:21 rootfs.ext2 lrwxrwxrwx 1 embed embed 11 Oct 12 15:21 rootfs.ext4 - rootfs.ext2 -rwxr-xr-x 1 embed embed 832 Oct 12 15:21 start-qemu.sh输出显示 ARM64 的gdbserver、测试程序debug_demo、内核镜像和 rootfs 均已生成。这只验证构建产物存在远程 GDB 调试是否成功还需按后续步骤连接并实际测试。七、启动 QEMU 并配置调试端口转发以下命令在 Ubuntu 的 Buildroot 源码目录运行。不要同时启动两台使用同一可写 rootfs 镜像的 QEMU。先记录所用 QEMU 的版本再启动客体/usr/bin/qemu-system-aarch64--version/usr/bin/qemu-system-aarch64\-Mvirt\-cpucortex-a53\-smp2\-m1G\-nographic\-kerneloutput/images/Image\-appendrootwait root/dev/vda consolettyAMA0\-drivefileoutput/images/rootfs.ext2,ifnone,formatraw,idhd0\-devicevirtio-blk-device,drivehd0\-netdevuser,idnet0,hostfwdtcp:127.0.0.1:5000-:2345\-devicevirtio-net-device,netdevnet0此例使用 Ubuntu 系统 QEMU。记录/usr/bin/qemu-system-aarch64 --version的实际输出如果换成 Buildroot 构建的 QEMU应明确记录路径和版本不要混写。hostfwd将 Ubuntu 的127.0.0.1:5000转发到客体的 TCP 2345。客户端将在同一台 Ubuntu 中运行因此无需向 Windows、局域网或公网开放这个端口。登录 Buildroot 后检查网卡ipaddriproute本次 BusyBox v1.37.0 的ip不支持-br执行ip -br addr会显示用法说明并不表示网络故障因此这里直接使用ip addr。若网卡已有 IPv4 地址和默认路由无需重复获取 DHCP 地址只有网卡没有 IPv4 地址时才根据实际名称执行例如udhcpc-ieth0QEMU 默认用户网络中客体常见地址是10.0.2.15。网卡名称和地址以实际输出为准如果 DHCP 失败检查内核 virtio 网卡驱动及客体网络配置。本次实测输出摘录如下省略无关网卡和 IPv6 信息# ip route default via 10.0.2.2 dev eth0 10.0.2.0/24 dev eth0 scope link src 10.0.2.15 # ip addr 3: eth0: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0 valid_lft forever preferred_lft forever输出确认eth0已启用IPv4 地址为10.0.2.15/24默认网关为10.0.2.2。本次在检查路由后还执行了udhcpc -i eth0成功获取同一地址但已有地址和默认路由时不需要重复这一步。这些结果只确认客体网络配置GDB 端口转发及远程连接仍需在后续步骤验证。八、在 ARM64 客体启动 gdbserver在 QEMU 的 Buildroot shell 中执行gdbserver--versiongdbserver :2345 /root/debug_demo预期出现类似输出PID 以实际结果为准Process /root/debug_demo created; pid ... Listening on port 2345这时程序等待 GDB 连接看起来终端停住是正常现象。暂时不要关闭这个终端也不要在 Ubuntu 上直接执行 ARM64 的debug_demo。gdbserver 没有常规的用户认证机制。本文只通过 Ubuntu 回环端口连接保持 QEMU 用户网络和受控实验环境不要把调试端口转发到0.0.0.0或公开网络。图示在 ARM64 客体中执行gdbserver :2345 /root/debug_demo后测试进程已创建本次 PID 为121。Listening on port 2345表示 gdbserver 正在监听客体的 TCP 2345 端口等待 Ubuntu 上的 GDB 客户端连接。此时尚未验证远程连接或命中断点保留该终端继续下一节操作。九、处理客户端兼容性问题并重新连接新开一个 Ubuntu 终端。若通过 PuTTY 使用虚拟机再建立一个到同一 Ubuntu 的 SSH 会话即可原会话保留 QEMU 和 gdbserver。1. 旧客户端能连接但出现寄存器解析错误本次最初使用 Ubuntu 的gdb-multiarch 9.2。它能够连接127.0.0.1:5000、设置断点并停在compute_total但出现以下关键警告和错误摘录warning: while parsing target description (at line 72): Vector v8bf16 references undefined type bfloat16 warning: Could not load XML target description; ignoring Remote g packet reply is too long (expected 788 bytes, got 804 bytes)此外读取目标加载器和 libc 时还出现.relr.dyn节类型无法识别及共享库架构警告。这些现象表明旧客户端与当前目标描述、寄存器布局及目标 ELF 格式存在兼容性问题不是简单的网络连接失败也不能通过隐藏警告解决。当时虽然print values[0]得到了10但函数参数显示中已有寄存器读取错误因此不能据此认定整个调试流程正常。处理方向是改用当前 Buildroot 构建的交叉 GDB 客户端再重新验证。2. 在 Ubuntu 构建交叉 GDB交叉 GDB 运行在 Ubuntu x86_64 主机上负责调试 ARM64 程序它不同于运行在客体中的 gdbserver也不是目标端的full debugger。先在旧(gdb)会话中执行quit若询问是否终止当前测试进程确认y。保留 QEMU等待客体恢复#提示符。在 Ubuntu 中执行cd~/buildroot-2025.02.8findoutput/host/bin-maxdepth1-name*-gdb-print如果没有交叉 GDB则执行make menuconfig按/搜索BR2_PACKAGE_HOST_GDB。本次搜索结果显示Symbol: BR2_PACKAGE_HOST_GDB [n] Prompt: Build cross gdb for the host Location: Toolchain按搜索结果对应的数字1跳转或返回主菜单进入Toolchain将Build cross gdb for the host设为[*]。本篇无需额外启用 Python、Simulator 或 TUI 支持。保存退出后检查配置再构建grep^BR2_PACKAGE_HOST_GDBy.configmakehost-gdb-j2echo$?确认第一条输出BR2_PACKAGE_HOST_GDBy后才构建echo $?必须紧接构建命令。这里只增加宿主机调试工具无需执行make clean、重新编译测试程序或重新生成 rootfs。本次构建记录显示echo $?返回0安装日志显示已生成output/host/bin/aarch64-buildroot-linux-gnu-gdb确认交叉 GDB 构建成功。3. 使用新客户端重新验证连接在 QEMU 的#提示符中重新执行gdbserver :2345 /root/debug_demo看到监听信息后保留该终端。然后在 Ubuntu 中执行cd~/buildroot-2025.02.8 output/host/bin/aarch64-buildroot-linux-gnu-gdb--versionoutput/host/bin/aarch64-buildroot-linux-gnu-gdb ./debug_demo这里使用本次安装日志中的实际路径。若你的工具链前缀不同用前面的find查到的路径替换不要继续启动旧的gdb-multiarch 9.2。记录新客户端及目标端的版本版本匹配有助于减少兼容性问题仍需以运行结果验证。进入新的(gdb)后逐条执行set pagination off set sysroot /home/embed/buildroot-2025.02.8/output/staging target remote 127.0.0.1:5000 break compute_total continuesysroot路径按实际用户名调整指向同一 Buildroot 构建产生的目标库目录帮助 GDB 找到目标的加载器和共享库不能使用 Ubuntu 的 x86_64 库替代。默认工具链 sysroot 中的库也可能没有完整调试符号本篇主要调试自己的程序。本次使用交叉 GDB 15.2 连接 gdbserver 15.2执行continue后已命中compute_total断点停在debug_demo.c第 5 行的int total 0;。本次截图中未再出现此前的目标描述解析失败和寄存器数据长度错误变量和调用栈检查结果见下一节。set pagination off关闭分页避免长输出停在--Type RET for more--提示处。调试命令应在(gdb)提示符后输入本次旧客户端截图中print count输入在分页提示处并未作为 GDB 命令执行。新客户端的连接、断点、变量和调用栈检查以及程序的最终输出和正常退出已验证单步执行属于尚未实测的延伸练习。十、断点、单步和变量检查1. 已实测参数、数组和调用栈命中compute_total断点后先检查变量不要立即再次执行continue否则程序可能直接运行结束失去当前函数的变量上下文。在断点处逐条执行list print count print values[0] print *values4 backtrace本次实测显示参数count为4values[0]为10数组内容为{10, 20, 30, 40}。调用栈中compute_total位于第 0 帧main位于第 1 帧确认当前函数由main调用。图示使用 Buildroot 交叉 GDB 连接 ARM64 客体命中compute_total断点。实测参数count为4数组内容为{10, 20, 30, 40}调用栈显示该函数由main调用。截图中未再出现此前的目标描述和寄存器数据长度错误。2. 延伸练习单步执行尚未实测以下为练习步骤和预期结果不属于本文已实测记录。若已执行continue使程序结束需要重新启动 gdbserver、连接并命中断点后再练习。通过next逐行执行在total初始化完成后再观察它next print total局部变量只有在相应作用域和初始化阶段之后才有意义。不要把尚未初始化时显示的值当作程序错误。重复next时可观察总和逐步变化具体停止行以 GDB 输出为准。若停在int total 0;执行一次next后查看total预期为0。随后每完成一次数组累加总和依次为10、30、60、100循环条件和索引更新也可能对应单步停止位置并非每次next都会改变总和。这里的单步结果仍待实测不属于上图已验证的内容。命令用途break 函数名在函数入口设置断点continue继续到下一断点或程序结束next执行下一源码行通常不进入被调用函数step单步执行遇到调用时可进入函数print 表达式查看参数、变量或表达式backtrace查看调用栈info breakpoints查看断点delete 断点编号删除指定断点若想练习step可在下一次实验中改为break main继续到main后用next走到调用compute_total的行再用step进入函数。程序已结束时需重新启动 gdbserver 并重新连接不能假定普通target remote会话直接支持run重启程序。十一、让程序完成并结束实验在 GDB 中执行continue本次执行continue后GDB 显示[Inferior 1 (process 131) exited normally]表示测试进程正常退出。切回 QEMU 的 gdbserver 终端可以看到本次实际输出total 100程序标准输出通常在客体的 gdbserver 终端不是在 Ubuntu 的 GDB 命令窗口中。图示GDB 执行continue后ARM64 客体中的测试程序输出total 100。客体记录的 PID 为131与 GDB 的正常退出信息一致确认本次程序完成计算并正常结束。此图展示最终运行结果不代表已验证单步过程中变量的变化。在 GDB 输入quit退出如果进程仍在调试中GDB 可能询问是否终止按当前实验需要确认。随后在 Buildroot shell 中执行poweroff正常关机完成后若 QEMU 未退出再按CtrlA松开后按X。十二、常见问题现象优先检查客体提示gdbserver: not found检查配置是否启用、镜像是否重新生成、启动的是不是新镜像GDB 连接超时或被拒绝确认 gdbserver 正在监听、客体网卡有地址、QEMU 带有 hostfwd 参数且 GDB 在同一 Ubuntu 中连接QEMU 提示端口转发失败Ubuntu 的 TCP 5000 可能已占用换一个端口并同步修改 GDB 连接地址GDB 提示没有调试符号检查-g、是否执行了 strip以及 GDB 加载的程序是否为本次编译产物变量显示optimized out使用-O0 -g重编译并将同一次编译产物重新部署缺少共享库符号或源码检查 sysroot本篇不要求系统库具有完整源码级调试信息bfloat16未定义或远程g数据包长度不匹配本次旧 GDB 9.2 出现此问题按第九节改用 Buildroot 交叉 GDB重新验证不要先改寄存器配置.relr.dyn类型无法识别或共享库架构警告本次旧客户端无法正确识别目标 ELF 信息先更换交叉 GDB再检查是否仍有警告输入print count却没有变量结果确认输入位置是(gdb)不是分页提示可用set pagination off关闭分页程序退出后提示No symbol count in current context进程已结束当前函数上下文不再存在重新启动 gdbserver 并连接命中断点后先检查变量不要立即再次continue程序修改后调试行号不对重新编译、更新 overlay、生成镜像确保 Ubuntu 与客体使用同一份程序十三、这次验证的边界本篇要验证的是 QEMU ARM64 Linux 中用户态进程的远程调试从交叉编译、部署到断点、变量和调用栈观察。当前已有记录确认了客体网络配置、gdbserver 启动和交叉 GDB 构建成功并通过交叉 GDB 15.2 与 gdbserver 15.2 验证了连接、命中断点、变量和调用栈检查。旧客户端暴露的兼容性错误在本次成功截图中未再出现。本次 GDB 与客体终端的记录还确认了同一测试进程正常退出最终输出为total 100。单步执行及过程中局部变量的变化仍需补充实测不能用最终输出替代单步验证。这里也不是通过 QEMU 的 CPU 调试接口调内核更不证明实体板的 JTAG、驱动或外设已验证。十四、下一步让调试程序随镜像一起生成这篇先用 overlay 放入测试程序。接下来可以继续把它写成 Buildroot 自定义软件包让源码编译、安装和镜像生成纳入同一套规则。后续计划《告别手动复制在 Buildroot 中添加自己的 ARM64 软件包》从一个 C 程序到随镜像自动安装的软件包继续在没有实体开发板的环境中练习完整的构建流程。参考资料Buildroot 官方手册GDB使用 gdbserverQEMU网络模拟上述链接可能指向当前版本文档具体配置和支持情况以本次所用版本为准。
阅读完成 · 觉得有帮助?