使用 Clion + QEMU/GDB 远程调试Linux内核

前言

之前写了一篇关于使用 Clion 来阅读linux源码的文章《使用Clion 阅读/修改/注释 Linux 内核源码》,通过使用make -j12转化为使用make -j12 vmlinux bzImage之后,大大的提高了编译的速度,以及很大的降低了对CLion占用内存的开销,不会再出现卡顿,今天来配置Clion的Remote Debug功能以可以对Linux kernel进行单步调试。

下面过程跳过了准备linux内核、qemu等等工具的准备,仅仅介绍最核心的重要的配置。

试验环境:

  • Linux-kernel:5.14.2 -
  • QEMU:6.1.0
  • HOST:Ubuntu 20.04.3 LTS
  • Clion:2020.3.4
  • GDB:GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
一、修改.config文件的配置
  1. 关闭编译选项CONFIG_RANDOMIZE_BASE,这是取消内核内存地址随机化(KASLR),此配置的信息如下(可通过“/",搜索此信息):
  │ Symbol: RANDOMIZE_BASE [=n]
  │ Type  : bool
  │ Defined at arch/x86/Kconfig:2095
  │   Prompt: Randomize the address of the kernel image (KASLR)
  │   Depends on: RELOCATABLE [=y] 
  │   Location: 
  │     -> Processor type and features
  │ (1)   -> Build a relocatable kernel (RELOCATABLE [=y])    

因为KASLR的位置可能随着内核版本的不同有所变化,因此最好手动搜索其具体的位置

  1. 打开编译选项CONFIG_DEBUG_SECTION_MISMATCH,如果关闭此选项,那么内核中仅仅被调用一次的函数会被编译优化为内联函数,不利于调试,此配置信息为:
  │ Symbol: DEBUG_SECTION_MISMATCH [=y]
  │ Type  : bool
  │ Defined at lib/Kconfig.debug:384
  │   Prompt: Enable full Section mismatch analysis
  │   Location:
  │     -> Kernel hacking
  │ (1)   -> Compile-time checks and compiler options
  1. 打开编译选项 DEBUG_INFO GDB_SCRIPTS

可以直接使用./scripts/config -e DEBUG_INFO -e GDB_SCRIPTS -e CONFIG_DEBUG_SECTION_MISMATCH -d CONFIG_RANDOMIZE_BASE来完成上述工作

二、修改Makefile中的编译优化等级

编辑Makefile,将其中的-O2 替还为 -O1,我修改过后的样子为:

export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \
			     -g -O1 -fomit-frame-pointer -std=gnu89
KBUILD_HOSTCXXFLAGS := -Wall -g -O1 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS)

ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
KBUILD_CFLAGS += -O1
else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3
KBUILD_CFLAGS += -O3
else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os
endif

完成上述,两处的配置,就可以根据《使用Clion 阅读/修改/注释 Linux 内核源码》来编译内核了

三、生成用于启动kernel的磁盘文件
mkinitramfs -o ramdisk.img
四、配置用于gdb调试的脚本文件
echo "add-auto-load-safe-path path/to/linux/scripts/gdb/vmlinux-gdb.py" >> ~/.gdbinit
五、启动qemu

进入到内核目录,执行:

qemu-system-x86_64 \
  -kernel arch/x86_64/boot/bzImage \
  -nographic \
  -append "console=ttyS0 nokaslr" \
  -initrd ramdisk.img \
  -m 1024 \
  -s -S

在这里很重要的一点,那就是在debug的时候不要加上--enable-kvm -cpu host等参数

到这里,将会进入暂停状态,再执行:

$ gdb vmlinux
(gdb) target remote :1234
(gdb) b start_kernel
(gdb) c

就可以使用gdb进行调试,如果出现断点不停、启动qemu-system-x86_64后直接启动了内核都是不正常的!

六、配置Clion

使用 Clion + QEMU/GDB 远程调试Linux内核_第1张图片

此时在执行完qemu-system-x86_64后,就可以点击debug按钮,进行调试

问题

目前调试并非完美,特别是对于inline函数的调试会出现无法进入函数、在非断点处停下等问题,这个问题和Clion无关,因为在GDB命令行模式下调试也会出现同样的问题!

不过瑕不掩瑜,只要好好的打断点,还是可以很好的调试的!

参考文献

  • Booting a Custom Linux Kernel in QEMU and Debugging It With GDB
  • Debugging kernel and modules via gdb
  • CLion调试Linux Kernel
  • 如何在编译linux内核时不优化内核以便于调试内核?
  • 用qemu + gdb调试linux内核

你可能感兴趣的:(linux,debug,gcc/gdb编译调试,kernel,qemu)