LoopJump's Blog

搭建Linux内核调试环境

2019-02-10

这篇文章介绍下在MacOSX如何用gdb + vmware的方式调试Linux内核。

一:安装Vmware Fusion

二:安装gdb

注意这里需要安装高版本的gdb,这里安装的是8.2版本

1
2
3
4
5
6
wget http://ftp.gnu.org/gnu/gdb/gdb-8.2.tar.gz
tar xf gdb-8.2.tar.gz
cd gdb-8.2
./configure --build=x86_64-apple-darwin14.0.0 --target=x86_64-vfs-linux --with-python
make
make install

三:下载guest os并安装

这里安装的是Ubuntu 18.04(内核版本4.18)

四:下载并安装新内核

这里下载4.19的内核,配置编译,注意:

1
2
3
4
5
CONFIG_RANDOMIZE_BASE=n(KASLR 内核地址随机化)
CONFIG_DEBUG_INFO=y (允许gdb调试)
CONFIG_GDB_SCRIPTS=y
CONFIG_X86_NEED_RELOCS=n (关闭内存动态布局)
CONFIG_RANDOMIZE_MEMORY=n
1
2
3
4
5
make -j16
make -j16 modules
make modules_install
make install
reboot

五:配置vmware,支持gdb远程调试

在虚拟机的安装目录下,找到包文件 Ubuntu 64 位 18.04,右键显示包内容,打开Ubuntu 64 位 18.04.vmx,添加一行内容:

1
debugStub.listen.guest64 = "1"

六:gdb调试

将编译出来的新内核的vmlinux从guest os拷贝到host os下的目录

启动vmware中的guest os

用gdb远程连接并调试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(gdb) file vmlinux
(gdb) target remote:8864
(gdb) b cmdline_proc_show # 虚拟机中执行 `cat /proc/cmdline` 触发断点
...
(gdb) bt
#0 cmdline_proc_show (m=0xffff88018763b500, v=0x1 <irq_stack_union+1>) at fs/proc/cmdline.c:8
#1 0xffffffff812ccdfa in seq_read (file=0xffff88016b348d00, buf=<optimized out>, size=<optimized out>, ppos=0xffffc9000368fee8) at fs/seq_file.c:229
#2 0xffffffff81324b8e in proc_reg_read (file=<optimized out>, buf=<optimized out>, count=<optimized out>, ppos=<optimized out>) at fs/proc/inode.c:231
#3 0xffffffff812a422a in __vfs_read (file=0xffff88018763b500, buf=<optimized out>, count=<optimized out>, pos=0xffffc9000368fee8) at fs/read_write.c:416
#4 0xffffffff812a43fe in vfs_read (file=0xffff88016b348d00, buf=0x7f4de8fa3000 <error: Cannot access memory at address 0x7f4de8fa3000>, count=131072, pos=0xffffc9000368fee8) at fs/read_write.c:452
#5 0xffffffff812a49c5 in ksys_read (fd=<optimized out>, buf=0x7f4de8fa3000 <error: Cannot access memory at address 0x7f4de8fa3000>, count=131072) at fs/read_write.c:578
#6 0xffffffff812a4a4a in __do_sys_read (count=<optimized out>, buf=<optimized out>, fd=<optimized out>) at fs/read_write.c:588
#7 __se_sys_read (count=<optimized out>, buf=<optimized out>, fd=<optimized out>) at fs/read_write.c:586
#8 __x64_sys_read (regs=<optimized out>) at fs/read_write.c:586
#9 0xffffffff8100427a in do_syscall_64 (nr=<optimized out>, regs=0x1 <irq_stack_union+1>) at arch/x86/entry/common.c:290
#10 0xffffffff81c00088 in entry_SYSCALL_64 () at arch/x86/entry/entry_64.S:238
Backtrace stopped: Cannot access memory at address 0x1fec0
(gdb) f 0
#0 cmdline_proc_show (m=0xffff88018763b500, v=0x1 <irq_stack_union+1>) at fs/proc/cmdline.c:8
8 {
(gdb) p m
$2 = (struct seq_file *) 0xffff88018763b500

扫描二维码,分享此文章