Step: 配置ssh的服务端host
(也可以直接在vscode中配置,忽略)
主要步骤:在~/.ssh/config中添加服务端的host,以便vscode的remote中能够登录
详细配置过程参考兄弟篇文章:ssh config如何配置用host名替代root@1.1.1.1
Step: vscode刷新远端服务器,并且点击打开
初次使用remote功能,需要在远端安装一个ssh的代理,需要耗费一定时间。
Step: 配置远端服务器安装C/C++的插件已支持debug功能
Step: 测试插件可用性
添加一个调试配置文件launch.json
{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "C++ Launch (GDB)", "type":"cppdbg", "request": "launch", "program": "${workspaceFolder}/test/1", "args": ["args1", "args2"], "environment": [{"name": "config", "value": "value"}], "cwd": "${workspaceFolder}" ] }
写一个C语言的测试进行实验测试:(注意调试的配置在workspace的.vscode目录的launch.json中)
C代码:
#include "stdio.h" int abc = 100; int main(void) { for (int i = 0; i < 100; i++) { abc = i; printf("abc: %d\n", abc); } return 0; }
文件创建好以后点击调试:
点击后C/C++ debug工具会自动编译和启动gdb进行调试:
添加断点,执行几个单步调试后,在两个地方通过-exec执行结果能够正确打印数据
如此,gdb通过vscode测试通过。下一步启动远端vmlinux的debug
Step: 添加远端vmlinux的launch配置
启动前需要远端能够在命令行就能支持vmlinux,这里只介绍通过vscode的,具体前置准备配置命令行的参考兄弟篇文章:如何不用vmlinux也能用gdb调试linux内核模块以及调试linux内核?、Linux内核中KASLR功能是什么?有什么作用?怎么破除?以及如何实操?
下面假设前置工作均已做好,添加一个launch的配置,核心原理是把vmlinux当做一个用户态程序,支持需要指定内存(这也是C语言的魅力所在)
依次点击添加配置:
选择:gdb启动这个
然后自动生成后修改对应参数,修改后注意json文件语法正确性。
修改后的launch代码:
//launch.json 每次系统重启后注意修改其中的symbol部分代码 { // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "debug vmlinux", "type": "cppdbg", "request": "launch", "program": "/usr/lib/debug/lib/modules/4.18.0-372.9.1.an8.x86_64/vmlinux", "args": [""], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", "coreDumpPath": "/proc/kcore", "setupCommands": [ //这里设置各种参数的,类似启动的时候, 输入给执行程序的, 比如设置一些环境参数 { "description": "为 gdb 启用整齐打印", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "将反汇编风格设置为 Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true }, { "description": "add ko symbol", "text": "add-symbol-file /path/to/your/ko.ko -s .text 0x12345678 -s .data 0x12345678", "ignoreFailures": true }, { "description": "modify vmlinux symbol, 注意修改前需要symbol-file去掉老的table", "text": "add-symbol-file /usr/lib/debug/lib/modules/4.18.0-372.9.1.an8.x86_64/vmlinux -s .data 0xffffffff87400000 -s .text 0xffffffff85e00000", "ignoreFailures": true } ], }, { "name": "C++ Launch (GDB)", "type":"cppdbg", "request": "launch", "program": "${workspaceFolder}/test/1", "args": ["args1", "args2"], "environment": [{"name": "config", "value": "value"}], "cwd": "${workspaceFolder}" } ] }
在gdb的命令行输入添加新的符号,需要先去掉原来的symbol-file重新加载
-exec symbol-file -exec add-symbol-file /usr/lib/debug/lib/modules/4.18.0-372.9.1.an8.x86_64/vmlinux -s .data 0xffffffffa8c00000 -s .text 0xffffffffa7600000 -exec p vm_numa_stat[3].counter
备注:vm_numa_stat[3].counter 是linux内核的一个全局变量,作为一个参考。为什么选择它,主要考虑2个点,不同内核版本稳定,运行中值不容易变化,调试确认方便
实操结果:
可以看到打印的值是30385,和命令行的一致。
后记
使用gdb命令行与vscode模式是一种比较绕的方式,在某些场景比较有实战价值。全过程操作依赖相当多前置动作,参考文中提到的文章。另外要达到最后的成功需要经过很多摸索稍有不慎就可能出错,不过把我C语言编译、链接、运行的本质,就没什么大的问题。