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

使用QEMU调试vmlinux时无法显示完整调用栈的问题求助

内核调试调用栈不完整问题解决方法

环境信息

  • 内核版本:5.10.145-rt74+
  • 调试工具:QEMU
  • QEMU版本:
qemu-system-aarch64 --version
QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.30)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
  • QEMU启动参数:
qemu-system-aarch64 -m 1024 -cpu max,sve=on,sve256=on -M virt,gic-version=3,its=on,iommu=smmuv3 -nographic -kernel arch/arm64/boot/Image -append "noinitrd nokaslr loglevel=8 sched_debug root=/dev/vda rootfstype=ext4 rw crashkernel=256M vfio.dyndbg=+pflmt irq_gic_v3_its.dyndbg=+pflmt iommu.dyndbg=+pflmt irqdomain.dyndbg=+pflmt" -drive if=none,file=/home/wzc/work/ext/temp/debug/git/rootfs_debian_arm64.ext4,id=hd0 -device virtio-blk-device,drive=hd0 --fsdev local,id=kmod_dev,path=./kmodules,security_model=none -device virtio-9p-pci,fsdev=kmod_dev,mount_tag=kmod_mount -s -S
  • VSCode GDB配置:
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "kernel debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/vmlinux",
            "cwd": "${workspaceFolder}",
            "MIMode": "gdb",
            "miDebuggerPath":"/usr/bin/gdb-multiarch",
            "miDebuggerServerAddress": "localhost:1234",
            "stopAtEntry": true,
        }
    ]
}

问题现象

调试时VSCode无法显示完整调用栈,停在未知即时编译代码处,调用栈信息:

__raw_spin_unlock_irqrestore(unsigned long flags, raw_spinlock_t * lock) (/home/wzc/work/ext/temp/debug/git/include/linux/spinlock_api_smp.h:161)
_raw_spin_unlock_irqrestore(raw_spinlock_t * lock, unsigned long flags) (/home/wzc/work/ext/temp/debug/git/kernel/locking/spinlock.c:194)
[Unknown/Just-In-Time compiled code] (Unknown Source:0)

调用栈异常截图

解决办法

1. 检查内核编译的调试配置

内核编译必须开启完整调试符号,打开.config文件确认以下选项:

CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF4=y  # 或DWARF5,更高版本调试信息更完整
CONFIG_FRAME_POINTER=y      # 开启帧指针是GDB正确回溯调用栈的关键

修改后重新编译内核和模块,生成带完整符号的vmlinux及模块文件,替换旧文件。

2. 调整QEMU的CPU参数

当前使用的-cpu max,sve=on,sve256=on,旧版QEMU(如4.2.1)对SVE指令集的调试支持存在兼容性问题,换成更稳定的CPU型号:

-cpu cortex-a76

同时确保nokaslr参数保留,KASLR会打乱内存地址,导致符号无法匹配。

3. 优化VSCode的GDB配置

在配置中添加setupCommands段,强制GDB识别ARM64架构、加载内核符号并处理模块:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "kernel debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/vmlinux",
            "cwd": "${workspaceFolder}",
            "MIMode": "gdb",
            "miDebuggerPath":"/usr/bin/gdb-multiarch",
            "miDebuggerServerAddress": "localhost:1234",
            "stopAtEntry": true,
            "setupCommands": [
                { "text": "set arch aarch64" },
                { "text": "symbol-file ${workspaceFolder}/vmlinux" },
                { "text": "add-symbol-file ${workspaceFolder}/kmodules/你的模块名.ko 模块加载地址" },
                { "text": "set unwindonsignal on" },
                { "text": "set print frame-arguments all" }
            ]
        }
    ]
}

模块加载地址可在QEMU启动后,登录目标系统执行cat /proc/modules获取。

4. 更新GDB版本

当前gdb-multiarch版本可能过旧,对ARM64 RT内核的调试支持不足,直接更新:

sudo apt update && sudo apt install gdb-multiarch

若更新后仍有问题,可从源码编译最新版GDB,确保支持ARM64的DWARF符号和帧指针回溯。

5. 适配RT内核特性

RT内核的自旋锁等机制为特殊实现,可能导致GDB回溯异常。若允许,调试时可暂时关闭RT特性,或编译内核时开启CONFIG_DEBUG_RT_MUTEXES等RT相关调试选项,帮助GDB识别RT代码的调用栈。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 06:31:07