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.东方财富|上海徐汇、南京|微信客户端查看职位(可自助提交信息,微信打开);
原文地址:https://www.cnblogs.com/Chary/p/15682360.html