背景
上一篇文章介绍了如何调试树莓派 Linux 内核 基于 J-Link + openocd + gdb 调试树莓派 4B Linux 内核 ,其中笔者基于 gdb + openocd + jlink 实现了内核调试。对于 gdb 老手来说,这样就已经足够了。然而,并不是人人都是 gdb 老手,笔者这个从上到下学习 Linux 的人也不是,图形化调试可能才是比较适合新手的方式。
经过一番研究后,笔者实现了通过 VSCode 来调试 Linux 内核,并将步骤分享在本文中。
步骤
准备源码 & 符号
将内核源码和符号拷贝到主机上,笔者在这里使用的是 Win 11 PC。源码和符号的获取可见上一篇文章。
配置 VSCode
安装 VSCode C 相关拓展
编写调试配置文件
将源码文件夹拖入到 VSCode 中后,在源码根目录的 .vscode 目录创建文件 launch.json,内容如下:
{
"version": "0.2.0",
"configurations": [
{
"name": "Linux Kernel Debug",
"type": "cppdbg",
"request": "launch",
"program": "C:\\Users\\xxx\\vmlinux",
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerServerAddress": "localhost:3333",
"hardwareBreakpoints": { "require": true, "limit": 6 },
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "将反汇编风格设置为 Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"miDebuggerPath": "C:\\SysGCC\\raspberry64\\bin\\aarch64-linux-gnu-gdb.exe"
}
]
}
其中 miDebuggerServerAddress是上一篇文章中 openocd 开启的 gdb server 的调试端口,miDebuggerPath 是上一篇文章中安装的 gdb 的路径,hardwareBreakpoints 是强制使能硬件断点的配置。
开始调试
开启上一篇文章提到的 openocd 后,点击 VSCode 调试选项卡的如下按钮后就可以开始调试了。
效果展示
调试启动后,点击下图中右上角的暂停按钮即可让系统停下来:
停下来之后可以查看各 CPU 上的 CALL STACK:
可以看到目前停在 cpu_do_idle,符合预期。
下面展示了笔者研究【cat /proc/[pid]/maps 中匿名内存映射(如下图下方展示的 [heap] [vvar] 等 vma)的名字是怎么得到的】过程中的调试截图。
$ sudo cat /proc/497/maps
55803e0000-55804b4000 r-xp 00000000 b3:02 17803 /usr/sbin/sshd
55804c3000-55804c7000 r--p 000d3000 b3:02 17803 /usr/sbin/sshd
55804c7000-55804c8000 rw-p 000d7000 b3:02 17803 /usr/sbin/sshd
55804c8000-55804cc000 rw-p 00000000 00:00 0
55a04a9000-55a04eb000 rw-p 00000000 00:00 0 [heap]
......
7f9cc0c000-7f9cc0e000 r--p 00000000 00:00 0 [vvar]
7f9cc0e000-7f9cc0f000 r-xp 00000000 00:00 0 [vdso]
......
7feee1e000-7feee3f000 rw-p 00000000 00:00 0 [stack]
从结果来看效果还是可以的,局部变量、调用栈、点击调用栈跳转源码等功能都正常工作。