【1000个GDB技巧之】如何在远端服务器打开通过vscode动态观测Linux内核实战篇?

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

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代码:

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代码:

json 复制代码
//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重新加载

c 复制代码
-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语言编译、链接、运行的本质,就没什么大的问题。

相关推荐
乙己4074 小时前
计算机网络——网络层
运维·服务器·计算机网络
飞行的俊哥4 小时前
Linux 内核学习 3b - 和copilot 讨论pci设备的物理地址在内核空间和用户空间映射到虚拟地址的区别
linux·驱动开发·copilot
空の鱼4 小时前
java开发,IDEA转战VSCODE配置(mac)
java·vscode
沈梦研5 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
hunter2062065 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb6 小时前
web服务器 网站部署的架构
服务器·前端·架构
不会飞的小龙人6 小时前
Docker Compose创建镜像服务
linux·运维·docker·容器·镜像
不会飞的小龙人6 小时前
Docker基础安装与使用
linux·运维·docker·容器
硬汉嵌入式6 小时前
《安富莱嵌入式周报》第349期:VSCode正式支持Matlab调试,DIY录音室级麦克风,开源流体吊坠,物联网在军工领域的应用,Unicode字符压缩解压
vscode·matlab·开源
%小农7 小时前
vscode的字体图标库-icomoon
ide·vscode·编辑器