gdb结合qemu-kvm调试linux内核

调试系统:
系统:Fedora 29
内核:5.0.6-200.fc29.x86_64

调试目标系统:
系统:CentOS 7.6
内核:3.10.0-957.10.1.el7.x86_64

在操作以下步骤之前,先用命令行方式启动虚拟机,参见我的另一篇文章:
https://blog.csdn.net/lonely_geek/article/details/89160627
在命令行后面加入 -s -S 启动gdb远程调试

1、下载并编译内核源码
在虚拟机上执行以下命令:

yumdownloader --source kernel-$(uname -r) //下载当前内核对应的源码包
rpm -ivh  kernel-3.10.0-957.10.1.el7.src.rpm
rpmbuild -bp ~/rpmbuild/SPECS/kernel.spec
cd ~/rpmbuild/BUILD/kernel-3.10.0-957.10.1.el7/linux-3.10.0-957.10.1.el7.x86_64/
make -j8 vmlinux

2、复制带调试信息的vmlinux文件和整个源代码到调试机:

scp  vmlinux  czh@192.168.122.1:~ 
cd ..	
make clean 
tar cvzf kernel.tar.gz linux-3.10.0-957.10.1.el7.x86_64/
scp  kernel.tar.gz  czh@192.168.122.1:~

[注:]复制的vmlinux文件在内核源码根目录下,大概有几百MB,带调试信息的。我们最终生成的内核(安装到boot下的,只有几MB,是不带调试信息的)

3、在调试机上将源代码解压,并将vmlinux移动到源代码根目录下

4、修改内核引导参数:
vi /etc/default/grub,
修改CMDLINE这一行,追加一个参数:nokaslr

 GRUB_CMDLINE_LINUX="crashkernel=256M rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb nokaslr"

[注:]nokaslr用于关闭内核起始地址随机化功能,如果不关闭,调试时会报类似错误:Cannot access memory at address 0xffffffff82819ad0

5、更新grub后重启虚拟机系统

 grub2-mkconfig --output /boot/grub2/grub.cfg
 reboot

6、调试机上执行过程如下:

[czh@localhost ~]$ cd kernel/
[czh@localhost kernel]$ gdb
GNU gdb (GDB) Fedora 8.2-6.fc29
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) file vmlinux  
Reading symbols from vmlinux...done.
(gdb) target remote :1234  
Remote debugging using :1234
native_safe_halt () at ./arch/x86/include/asm/irqflags.h:54
54	}
(gdb) b vfs_read
Breakpoint 1 at 0xffffffff812414e0: file fs/read_write.c, line 451.
(gdb) c
Continuing.
[Switching to Thread 19]

Thread 19 hit Breakpoint 1, vfs_read (file=file@entry=0xffff880035434600, buf=buf@entry=0x7f40c4e1cb80 "\b", count=count@entry=272, pos=pos@entry=0xffff88022dff7f18)
    at fs/read_write.c:451
451	{
(gdb) list
446	}
447	
448	EXPORT_SYMBOL(do_sync_read);
449	
450	ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
451	{
452		ssize_t ret;
453	
454		if (!(file->f_mode & FMODE_READ))
455			return -EBADF;
(gdb) c
Continuing.

Thread 19 hit Breakpoint 1, vfs_read (file=file@entry=0xffff880035434600, buf=buf@entry=0x7f40c4e1cb80 "\b", count=count@entry=272, pos=pos@entry=0xffff88022dff7f18)
    at fs/read_write.c:451
451	{

7、其他事项
1)gdb搜索源代码路径可以自己修改,利用下面一些命令即可:
directory path-list:将一个或者多个源代码搜索目录加入到当前源码搜索目录列表的前面,目录之间使用空格间隔。
directory:不带参数的directory将源码搜索目录恢复为默认值。
set directories path-list:将源码目录设置为path-list,但是会补上默认目录。
show directories:显示源码搜索目录列表。
2) 调试内核模块:内核模块并非集成在内核中,所以先要提前加载模块符号,让gdb找到相应的地址:
add-symbol-file xxx.ko 0x+地址 (需要写成0x开头)
(对应模块的.text起始地址,可以从/sys/module/xxx/sections/.text获取)
3)调试64位内核可能会出现有些函数无法被hit,例如b start_kernel,重启后并未断在此处。解决方法参考:https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944
使用hard break即可,例如:hb start_kernel
原文:-----------------------------------------------------------------------------------------------------
More details:

  • It works if I use hbreak (GDB hardware-assisted breakpoints) instead of break for the very first breakpoint.
  • After this first breakpoint, normal “break” breakpoints work fine, too.
  • Accoording to http://chemnitzer.linux-tage.de/2012/vortraege/folien/1061-VirtualDebugging.pdf slide 18 this might be due to GDB not properly dealing with protocol changes. In this case, this is a GDB bug/issue, not a qemu-kvm one.
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值