如何使用GDB调试Linux内核
编译Linux内核 1 2 3 4 5 6 export ARCH=x86 make menuconfig make -j 8
在menuconfig中配置
1 2 3 4 5 6 7 8 9 Kernel hacking ---> [*] Kernel debugging Compile-time checks and compiler options ---> [*] Compile the kernel with debug info [*] Provide GDB scripts for kernel debuggin Processor type and features ----> [] Randomize the address of the kernel image (KASLR)
安装qume
下载好qemu后,./configure prefix=/to/path/ 配置好安装路径
make 编译
制作根目录 一个最小的Linux系统需要img文件和一个根目录 ,制作根目录有很多软件,我们使用busybox。
步骤:
使用dd命令创建文件,并格式化为ext4文件系统:
1 2 3 szp@r420-PowerEdge-R420:~/busybox-1.32.0$ dd if =/dev/zero of=rootfs.img bs=1M count=10 szp@r420-PowerEdge-R420:~/busybox-1.32.0$ mkfs.ext4 rootfs.img
创建用于挂载该镜像文件的目录fs,挂载后才能往里面写入busybox。 使用mount命令将rootfs.img挂载到fs目录,编译busybox并写入fs目录中。
1 2 3 4 5 szp@r420-PowerEdge-R420:~$ mkdir fs szp@r420-PowerEdge-R420:~/busybox-1.32.0$ sudo mount -t ext4 -o loop rootfs.img ./fs szp@r420-PowerEdge-R420:~/busybox-1.32.0$ sudo make install CONFIG_PREFIX=./fs
接下来对写入的busybox进行补充配置:
1 2 3 4 5 6 szp@r420-PowerEdge-R420:~/busybox-1.32.0/fs$ sudo mkdir proc dev etc home mnt szp@r420-PowerEdge-R420:~/busybox-1.32.0/fs$ sudo cp -r ../examples/bootfloppy/etc/* etc/ szp@r420-PowerEdge-R420:~/busybox-1.32.0$ sudo chmod -R 777 fs/
最后,卸载rootfs.img:
1 szp@r420-PowerEdge-R420:~/busybox-1.32.0$ sudo umount fs
至此已经制作好了根文件目录,下面我们启动qemu
启动qemu 1 szp@r420-PowerEdge-R420:~$ qemu-system-x86_64 -kernel ~/linux-4.14.191/arch/x86_64/boot/bzImage -hda ~/busybox-1.32.0/rootfs.img -append "root=/dev/sda console=ttyS0" -s -S -smp 1 -nographic
该命令的参数注释:
至此我们已经完成了大部分操作只需要,新启动一个shell,然后执行:
1 2 3 4 5 gdb ./linux-5.0/vmlinux target remote localhost :1234
查看gdb支持的lx函数或命令:apropos lx
vmlinux 是编译内核时生成的调试文件,在内核源码的根目录中。
参考资料 http://kerneltravel.net/blog/2021/debug_kernel_szp/
https://mazhen.tech/p/%E4%BD%BF%E7%94%A8gdb%E8%B0%83%E8%AF%95linux%E5%86%85%E6%A0%B8/#%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E
使用vscode+qemu+gdb调试Linux内核
直接使用物理机进行调试 除开使用虚拟机安装内核后,还可以直接在平台上通过安装内核调试符号包来进行调试。
查询系统的版本
下载调试包 已知自己的版本通过这个版本号去这个网站下载调试包,注意的是下载的调试包需要和自己的系统版本对应Ubuntu官方网站下的调试包
linux-image-unsigned-5.13.0-52-generic-dbgsym_5.13.0-52.59~20.04.1_amd64.ddeb 这是我的系统对应的版本。
安装内核源码
这里需要注意的是:amd64就是x86-64也称之intel64
1 2 3 4 5 6 7 8 $ sudo apt-cache search linux-source linux-source - Linux kernel source with Ubuntu patches linux-source-5.13.0 - Linux kernel source for version 5.13.0 with Ubuntu patches $ sudo apt install linux-source-5.13.0 $ sudo cd /usr/src $ sudo tar -jxvf linux-source-5.13.0.tar.bz2 $ sudo cd /usr/src/linux-source-5.13.0
创建软链接
1 2 3 4 $ mkdir -p /build/linux-lpF6wX/ $ ln -s /usr/src/linux-source-5.13.0 /build/linux-lpF6wX/linux-5.13.0
开始调试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 gdb /usr/lib/debug/boot/vmlinux-5.13.0-20-generic (gdb) list *__x64_sys_mount 0xffffffff81352ce0 is in __x64_sys_mount (/build/linux-lpF6wX/linux-5.13.0/fs/namespace.c:3451). warning: Source file is more recent than executable. 3446 /* ... and return the root of (sub)tree on it */ 3447 return path.dentry; 3448 } 3449 EXPORT_SYMBOL(mount_subtree); 3450 3451 SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, 3452 char __user *, type , unsigned long, flags, void __user *, data) 3453 { 3454 int ret; 3455 char *kernel_type; (gdb) disassemble *__x64_sys_mount ... 0xffffffff81352de3 <+259>: call 0xffffffff813524c0 <path_mount> 0xffffffff81352de8 <+264>: lea -0x40(%rbp),%rdi 0xffffffff81352dec <+268>: movslq %eax,%r12 0xffffffff81352def <+271>: call 0xffffffff813321b0 <path_put> ...
通过在 gdb 工作窗口中 list *__x64_sys_mount
我们就可以看到源码相关的定义,一切准备完成,可以愉快地进行相关工作调试了。
参考资料 http://advdbg.org/blogs/advdbg_system/articles/7147.aspx
https://www.ebpf.top/post/ubuntu-21-10-dbgsym/
https://blog.csdn.net/qq_30952829/article/details/126571506