之前写了一篇关于使用 Clion 来阅读linux源码的文章《使用Clion 阅读/修改/注释 Linux 内核源码》,通过使用make -j12
转化为使用make -j12 vmlinux bzImage
之后,大大的提高了编译的速度,以及很大的降低了对CLion占用内存的开销,不会再出现卡顿,今天来配置Clion的Remote Debug功能以可以对Linux kernel进行单步调试。
下面过程跳过了准备linux内核、qemu等等工具的准备,仅仅介绍最核心的重要的配置。
试验环境:
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的位置可能随着内核版本的不同有所变化,因此最好手动搜索其具体的位置
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
DEBUG_INFO
GDB_SCRIPTS
可以直接使用./scripts/config -e DEBUG_INFO -e GDB_SCRIPTS -e CONFIG_DEBUG_SECTION_MISMATCH -d CONFIG_RANDOMIZE_BASE
来完成上述工作
编辑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 内核源码》来编译内核了
mkinitramfs -o ramdisk.img
echo "add-auto-load-safe-path path/to/linux/scripts/gdb/vmlinux-gdb.py" >> ~/.gdbinit
进入到内核目录,执行:
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后直接启动了内核都是不正常的!
此时在执行完qemu-system-x86_64后,就可以点击debug按钮,进行调试
目前调试并非完美,特别是对于inline函数的调试会出现无法进入函数、在非断点处停下等问题,这个问题和Clion无关,因为在GDB命令行模式下调试也会出现同样的问题!
不过瑕不掩瑜,只要好好的打断点,还是可以很好的调试的!