• Linux 内核终于可以 debug 了!


    低并发编程 战略上藐视技术,战术上重视技术  

    今天终于成功 debug 了 Linux 内核,允许我一惊一乍给大家分享下喜悦吧!

    之前读 Linux 的源码,一直想着如果能 debug 就好了。

    无奈 Java 出身的我,本来对 c 就很不熟,跑起一个 c 代码就很费劲了,更别说调试,而且还是调试这种和普通 c 项目不一样的内核代码。

    仅仅是出于学习 Linux 内核源码的目的想要调试,所以不想花太多时间研究如何构建这个调试环境,想着在网上找个教程,一次性部署好之后就一直用了,无奈一直没找到能照着文档就搭建成功的。

    今天终于找到一个大佬的文档,直接按上面说的就能操作成功,分享给大家,同时我自己也做个备份。

    先照着这个文档,使得可以用 gdb 进行调试:

    https://wenfh2020.com/2021/05/19/gdb-kernel-networking/

    再按照这个文档,用 vscode 进行更直观地调试(当然也是 gdb 方式):

    https://wenfh2020.com/2021/06/23/vscode-gdb-debug-linux-kernel/

    最终效果是。

    虚拟机这边用 qemu 启动 Linux 5.0.1 内核。

    图片

    本机这边用 vscode 的 ssh-remote 插件远程连接虚拟机,然后用 gdb debug。

    图片

    给大家放大点。

    图片

    main.c 下的主方法。

    看到断点进来相当激动了!这个文档我可得保存好,虚拟机镜像也不敢动了,哈哈,以后就可以开开心心 debug Linux 内核啦。

    不过中间也踩了好多坑,原本我想着灵活一点,用自己的 ubuntu 版本,用自己想调试的 Linux 内核版本,无奈都失败了,中间有各种奇奇怪怪的问题...

    我就放弃了,乖乖先按照人家的文档跑起来再说吧~

    不知道文档里是不是有多余操作,反正各种骚操作我是看不懂,还要改 gdb 的源码。

    之后我看看能不能把低版本的 Linux 也搞通,如果大家有更方便地调试方法,可以教教我,这块真是空白。

     Linux 内核终于可以 debug 了! (qq.com)

    gdb 调试 Linux 内核网络源码(附视频)

    最近在看 Linux 内核的网络部分源码,在 MacOS 上搭建调试环境,通过 gdb 调试,熟悉内核网络接口的工作流程。

    调试环境是跑在虚拟机里的,在 windows 上应该也能将环境搭建起来。


    1. 目标


    2. 视频

    视频连接:gdb 调试 Linux 内核网络源码


    3. 流程

    • 下载 ubuntu 14.04
    1
    
    http://mirrors.aliyun.com/ubuntu-releases/14.04/ubuntu-14.04.6-desktop-amd64.iso
    
    • vmware 安装 ubuntu。
    1. 虚拟系统磁盘空间,尽量给大一些,例如 100 G。
    2. 通过 root 权限安装 linux 内核。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    # 设置 root 密码。
    sudo passwd
    # 切换 root 用户。
    su root
    
    # 安装部分工具。
    apt-get install vim tmux openssh-server git -y
    
    # 添加 alias 方便操作终端。
    vim ~/.bashrc
    # 添加 alias c='clear'
    source ~/.bashrc
    
    # 启动 ssh. 避免后面 qemu 调试导致界面卡死,可以远程关闭进程。
    ps -e | grep ssh
    sudo /etc/init.d/ssh start
    
    • 下载编译 linux 内核。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    # 下载内核源码。
    cd /root
    wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.0.1.tar.xz
    xz -d linux-5.0.1.tar.xz
    tar -xvf linux-5.0.1.tar
    cd linux-5.0.1
    
    apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev -y
    
    # 设置调试的编译菜单。
    make menuconfig
    
    # 下面选项如果没有选上的,选上,然后 save 保存设置,退出 exit。
    Kernel hacking  --->
         Compile-time checks and compiler options  ---> 
             [*] Compile the kernel with debug info
             [*]     Provide GDB scripts for kernel debugging
    
    
    Processor type and features  --->
        [*] Randomize the address of the kernel image (KASLR) 
    
    # 编译内核。
    make -j8
    
    mkdir rootfs
    
    • 调试内核。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    # 下载测试项目。
    cd ..
    git clone https://github.com/mengning/menu.git
    cd menu
    vim Makefile
    # 修改编译项:
    # qemu-system-x86_64 -kernel ../linux-5.0.1/arch/x86/boot/bzImage -initrd ../rootfs.img
    
    # 安装模拟器 qemu 和编译环境。
    apt install qemu libc6-dev-i386
    
    # 编译测试项目。
    make rootfs
    
    # 调试 kernel
    qemu-system-x86_64 -kernel ../linux-5.0.1/arch/x86/boot/bzImage -initrd ../rootfs.img -append nokaslr -S -s
    
    cd ../linux-5.0.1
    
    # 发现低版本的 gdb 调试出现问题,需要升级。
    gdb ./vmlinux
    
    • 安装高版本 gdb
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    cd /root
    gdb -v | grep gdb
    apt remove gdb -y
    sudo add-apt-repository ppa:ubuntu-toolchain-r/test
    sudo apt install software-properties-common
    sudo apt-get update
    sudo apt-get install gcc-snapshot -y
    gcc --version
    sudo apt install gcc-9 g++-9 -y
    sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 --slave /usr/bin/g++ g++ /usr/bin/g++-9
    gcc --version
    #wget https://mirror.bjtu.edu.cn/gnu/gdb/gdb-8.3.tar.xz
    wget http://ftp.gnu.org/gnu/gdb/gdb-8.3.tar
    tar -xvf gdb-8.3.tar.xz
    cd gdb-8.3
    # 修改 gdb/remote.c 代码。
    vim gdb/remote.c
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    /* Further sanity checks, with knowledge of the architecture.  */
    // if (buf_len > 2 * rsa->sizeof_g_packet)
    //   error (_("Remote 'g' packet reply is too long (expected %ld bytes, got %d "
    //      "bytes): %s"),
    //    rsa->sizeof_g_packet, buf_len / 2,
    //    rs->buf.data ());
    
    if (buf_len > 2 * rsa->sizeof_g_packet) {
        rsa->sizeof_g_packet = buf_len;
        for (i = 0; i < gdbarch_num_regs(gdbarch); i++) {
            if (rsa->regs[i].pnum == -1)
                continue;
            if (rsa->regs[i].offset >= rsa->sizeof_g_packet)
                rsa->regs[i].in_g_packet = 0;
            else
                rsa->regs[i].in_g_packet = 1;
        }
    }
    
    1
    2
    3
    4
    5
    
    ./configure
    make -j8
    cp gdb/gdb /usr/bin/
    sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 0 --slave /usr/bin/g++ g++ /usr/bin/g++-9
    sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 100
    
    • 调试 tcp 网络通信。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    cd /root/linux-5.0.1
    git clone https://github.com/mengning/linuxnet.git
    # 拷贝文件到 menu
    cd linuxnet/lab2
    # 修改拷贝的路径。
    vim Makefile
    # cp test_reply.c ../../../menu/test.c
    # cp syswrapper.h ../../../menu
    
    make
    
    cd ../../../menu
    make rootfs
    cd ../linux-5.0.1/linuxnet/lab3
    # qemu-system-x86_64 -kernel ../../arch/x86/boot/bzImage -initrd ../rootfs.img
    
    make rootfs
    
    # 调试
    qemu-system-x86_64 -kernel ../../arch/x86/boot/bzImage -initrd ../rootfs.img -append nokaslr -S -s
    
    1
    2
    3
    4
    5
    6
    7
    8
    
    cd /root/linux-5.0.1
    gdb ./vmlinux
    # 下断点。
    b tcp_v4_connect
    b inet_csk_accept
    # gdb 远程连接调试程序。
    target remote : 123
    c
    

    用户可以根据自己的需要去下断点,也可以修改 linuxnet 源码进行调试。


    4. vscode + gdb

    vscode + gdb 调试 Linux 内核更人性化一点。

    详看:vscode + gdb 远程调试 linux 内核源码(附视频)


    5. 参考

    vscode + gdb 远程调试 linux 内核源码(附视频)

    前段时间才搭建起来 gdb 调试 Linux 内核网络源码视频 ),但是 gdb 命令调试效率不高。磨刀不误砍柴工,所以折腾一下 vscode,使调试人性化一点。


    1. 视频

    视频连接:vscode + gdb 远程调试 linux (EPOLL) 内核源码


    2. 搭建调试环境

    要搭建 vscode + gdb 调试 Linux 内核环境,首选要搭建:gdb 调试 Linux 内核源码视频,然后再配置 vscode 进行测试调试。


    3. vscode 配置

    3.1. vscode 插件

    • ms-vscode.cpptools
    • remote-ssh

    避免 remote-ssh 工作过程中频繁要求输入登录密码,最好设置一下 ssh 免密码登录(参考:[shell] ssh 快捷登录)。


    3.2. 项目调试配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "kernel-debug",
                "type": "cppdbg",
                "request": "launch",
                "miDebuggerServerAddress": "127.0.0.1:1234",
                "program": "${workspaceFolder}/vmlinux",
                "args": [],
                "stopAtEntry": false,
                "cwd": "${workspaceFolder}",
                "environment": [],
                "externalConsole": false,
                "logging": {
                    "engineLogging": false
                },
                "MIMode": "gdb",
            }
        ]
    }

    4. 测试调试

    4.1. 虚拟机操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    # 虚拟机进入 linux 内核源码目录。
    cd /root/linux-5.0.1
    
    # 从 github 下载内核测试源码。
    git clone https://github.com/wenfh2020/kernel_test.git
    
    # 进入测试源码目录。
    cd kernel_test/test_epoll_tcp_server
    # make 编译
    make
    # 通过 qemu 启动内核测试用例。
    make rootfs
    # 在 qemu 窗口输入小写字符 's', 启动测试用例服务程序。
    s
    # 在 qemu 窗口输入小写字符 'c', 启动测试用例客户端程序。
    c
    
    # 通过 qemu 命令启动内核测试用例进行调试。
    qemu-system-x86_64 -kernel ../../arch/x86/boot/bzImage -initrd ../rootfs.img -append nokaslr -S -s
    # 在 qemu 窗口输入小写字符 's', 启动测试用例服务程序。
    s
    # 在 qemu 窗口输入小写字符 'c', 启动测试用例客户端程序。
    c
    

    4.2. 实体机操作

    1. vscode 连接远程虚拟机。
    2. vscode 打开虚拟机 Linux 内核源码。
    3. vscode 在 Linux 内核源码的 eventpoll.c 文件,对对应接口(epoll_create, epoll_wait, epoll_ctl)下断点。
    4. F5 快捷键启动 vscode 调试。

    5. 小结

    • 我认为在阅读 Linux 内核源码前,最好先把调试环境搭建起来,因为 Linux 内核源码庞大复杂,新手很难从复杂的源码调用关系中理清思路。
    • 老师传道受业,只会给你指出一条学习路线,还会提醒你路上可能遇到哪些大坑,但是路上还有无数小坑,你只有通过实践调试,才能找到答案。
    • 在求知的路上,让我们共勉!

    Ubuntu18.04编译调试OpenJDK15 - 知乎

    Ubuntu18.04编译调试OpenJDK15

    Ubuntu18.04编译调试OpenJDK15

    自从 Oracle Java SE support Roadmap 更新, OpenJDK就分为了 Oracle's OpenJDK和 AdoptOpenJDK

    • Oracle's OpenJDK : Oracle从JDK 9开始开始发布基于GPL协议的开源构建版本,从JDK 11开始,Oracle's OpenJDK和Oracle JDK在功能上几乎完全一致
    • AdoptOpenJDK : 由社区维护的发行版本,纯血的OpenJDK

    获取OpenJDK源码

    OpenJDK 社区采用mercurial 作为版本控制工具. 安装mercurial

    $ sudo apt install mercurial

    安装完成后即可下再OpenJDK源码, 可以在 OpenJDK Repositories 中找到对应的版本,并通过mercurial下载源码

    以OpenJDK最新版本Master + dev为例

    $ hg clone https://hg.openjdk.java.net/jdk/jdk

    经过漫长的等待后 通过

    $ bash get_source.sh

    获取源码,尽量多重复获取几次,因此单次下载不一定完整,直到不出现如下提示即下载完整了

    WARNING: langtools exited abnormally (255)
    WARNING: nashorn exited abnormally (255)

    boot JDK

    构建OpenJDK需要一个预先存在的JDK。这称为“boot JDK”

    Boot JDK最好是当前版本的前一个版本,即 n-1,因此选择下载 OpenJDK 14 下载完后解压备用

    Build AdoptOpenJDK

    $ cd ${OpenJDK源码目录}
    $ bash configure --with-boot-jdk=${YourBootJDKPath} --with-debug-level=slowdebug

    其中 :

    • --with-boot-jdk : 表示指定boot JDK的路径,如果已经设置了JAVA_HOME则无需指定
    • --with-debug-level : 表 设置debug等级,可选值为release,fastdebug,slowdebugoroptimized. 默认为releaseslowdebug表示没有优化,有debug log 其定义于 Define

    然后过程中会检查系统依赖,如果缺少依赖会提示安装, 下面是所有需要安装的依赖

    $ sudo apt-get install autoconf
    $ sudo apt-get install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev
    $ sudo apt-get install libcups2-dev
    $ sudo apt-get install libfontconfig1-dev
    $ sudo apt-get install libasound2-dev

    直到出现如下信息表示配置完成:

    summary

    它会在 build/目录生成相应的 configuration , 然后通过

    $ make all

    编译.

    值得注意的是 如果有多份configurations那么就需要在 CONF环境变量中指定配置不然会如下错误

    未指定configuration

    可以指定CONF环境变量 即可开始编译

    $ CONF=linux-x86_64-server-slowdebug make all

    风扇的呼啸

    大概10分钟左右编译完成.

    完成之后可以在 build/linux-x86_64-server-slowdebug/jdk/bin中执行./java -version

    调试

    这里选择使用vscode调试, OpenJDK提供了一个命令

    $ make vscode-project

    可以快速生产vscode workspace.

    我这里使用vscode remote 连接到 Ubuntu中,然后 vscode File-> Open Workspace... 选择 build/linux-x86_64-server-slowdebug/jdk.code-workspace即可,然后根据提示安装相应的插件

    安装完成后需要reloadvscode

    然后 Run->Open Configurations打开launch.json 在 "name": "java" 的配置中加上 "args": ["-version"] ,然后 F5即可看到如下结果

    众所周知... C/C++ 的入口为 main 函数, 所以 打开 main.c文件, 下一个断点.. 就可以愉快的玩耍了...

    更多编译的选项可以阅读官方文档...

    =========================

    工作机会(内部推荐):发送邮件至gaoyabing@126.com,看到会帮转内部HR。

    邮件标题:X姓名X_X公司X_简历(如:张三_东方财富_简历),否则一律垃圾邮件!

    公司信息:

    1. 1.东方财富|上海徐汇、南京|微信客户端查看职位(可自助提交信息,微信打开);
  • 相关阅读:
    给video添加自定义进度条
    高德地图鼠标获取经纬度
    高德地图行政区域划分
    面试经验之谈
    Hybrid App 开发模式
    运维 08 常用服务安装部署
    运维 07 Linux系统基础优化及常用命令
    运维 06 vim与程序员
    运维 05 Shell基本命令
    运维 04 Shell基础命令(二)
  • 原文地址:https://www.cnblogs.com/Chary/p/15682360.html
Copyright © 2020-2023  润新知