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

如何在汇编代码中设置断点?能否用GDB调试Linux启动汇编代码?

调试Linux启动汇编代码(header.S)及GDB可行性解答

GDB完全可行,而且是调试Linux内核启动流程(包括header.S这类汇编入口代码)的标准工具,通常和QEMU配合使用,下面是具体的调试步骤和关键操作:

1. 编译带调试信息的内核

内核默认编译会剥离调试符号,必须先开启调试信息配置:

  • 执行make menuconfig,进入Kernel hacking -> Compile-time checks and compiler options,勾选Compile the kernel with debug info(对应CONFIG_DEBUG_INFO)
  • 保存配置后,执行make -j$(nproc)编译内核,确保生成的vmlinux包含完整调试符号

2. 用QEMU启动内核并开启调试模式

使用以下命令启动QEMU,让它暂停在启动初期并监听调试端口:

qemu-system-x86_64 -kernel arch/x86/boot/bzImage -s -S
  • -s:默认开启TCP端口1234,供GDB连接
  • -S:启动后立即暂停,不自动执行代码,等待GDB指令

3. 连接GDB并加载调试符号

打开另一个终端,启动GDB并连接QEMU:

gdb vmlinux
  • 在GDB中执行target remote localhost:1234,建立和QEMU的调试连接
  • 若header.S属于boot阶段的setup程序,可额外加载setup的符号文件:file arch/x86/boot/setup.elf

4. 设置断点并开始单步调试

  • 定位关键位置:
    若知道header.S入口的内存地址,直接用break *0x<入口地址>设置断点;若符号存在,可直接用break Main(针对header.S中的Main函数);要追踪到start_kernel,直接设置break start_kernel
  • 单步调试指令:
    • si:单步执行一条汇编指令(会进入函数调用,比如Main函数内部)
    • ni:单步执行一条汇编指令(跳过函数调用,直接执行下一条)
  • 查看寄存器、PC及内存状态:
    • info registers:查看所有寄存器的当前值(x86架构下PC对应rip寄存器)
    • x/10i $rip:显示当前PC附近的10条汇编指令
    • x/16xw 0x<内存地址>:查看指定内存地址开始的16个32位十六进制值
    • display $rip:设置自动显示PC值,每次单步后自动更新
    • display $rax:追踪特定寄存器(比如rax)的变化,替换成你需要关注的寄存器即可

5. 追踪内核解包过程

内核解包完成后会从setup阶段跳转到vmlinux的入口,此时GDB会自动识别新的指令流,若符号加载正常,就能继续追踪到start_kernel的执行;若跳转后符号不匹配,可重新执行file vmlinux确保符号正确加载

关于Visual Studio的补充

VS可以通过WSL配合GDB调试,或者使用VS的GDB插件连接QEMU,但GDB+QEMU是更轻量、原生的Linux内核调试方案,适合专注于启动汇编代码的追踪

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 09:56:28