kdump定位

一、准备工具

1、crash工具,可直接用yum下载
2、内核调试信息,编译内核时打开调试(有些标准内核版本可在网上下载调试信息)
menuconfig中内核调试信息开关路径:
Kernel hacking -> Compile-time checks and compiler options在这里插入图片描述
3、core文件

二、初识vmcore-dmesg

vmcore-dmesg.txt会将内核crash的原因以及当时的函数调用栈打出来,我们能从中获取一些基本信息。
在这里插入图片描述
在这里插入图片描述

三、使用ko以及vmcore进行调试

先使用gdb调试出错的模块ko(使用前面编译出的带调试信息的内核编译一个新的ko)。然后找到出错的语句,以iodir_bdev_handle+0x188为例:
l* iodir_bdev_handle+0x188
在这里插入图片描述
可以看到具体出错的语句就在函数的2000行。
然后可以先看源代码,先缩小问题的范围,方便定位。下面贴出部分代码,也方便后续对照汇编来看:
在这里插入图片描述
在这里插入图片描述
从2000行的代码中可以看到操作空指针可能是dio或者bvec引起,而bvec取的是bv的地址,bv是在一开始分配的结构体,所以这里操作空指针很大可能就是dio或者是其内部成员sg。
然后我们看dio分配的代码段,dio最初被初始化为NULL,然后分配空间调用的接口为
dio = iodir_dio_alloc(CFP_ATOMIC, num)。若未给dio分配空间,这里会直接退出,不会到2000行操作空指针。所以可以基本确定操作空指针的问题出在sg上,而这里的num用于指定sg的个数(内层代码就不贴了),如果我们将这里的num值打印出来确实是0就能印证猜想,后面会贴出如何打印数据的截图。
这里仅仅是举个例子,表明可以先通过分析代码缩小范围,如果直接查看代码得不到太多直观的信息,可配合core文件和汇编代码来分析。

调试vmcore文件:
在这里插入图片描述
crash vmcore vmlinux,然后使用bt命令获取栈信息

这里主要关注这些寄存器的信息,然后配合函数的汇编代码看。
上面第一行exception RIP表明出错的指令的位置
后面是一些栈指针、指令指针、通用寄存器的一些数据,有些在后面需要用到
首先我们找到出错时IP的值,iodir_bdev_handle+392,所以我们这里将iodir_bdev_handle的汇编代码打出来,查看其392行的指令
这里我们贴出部分汇编代码
disass iodir_bdev_handle
在这里插入图片描述
在这里插入图片描述
可以看到,第rip所指的指令为mov %rdx,(%rcx,%rax,1),这句指令翻译过来就是:
取rdx寄存器保存的地址的数据,放到rcx + rax * 1这个地址里面去(由于这里汇编使用的是AT&A规范,目标操作数在源操作数的右边)。
配合c代码看这句话的意思就很清楚了,前面我们已经知道出错代码在2000行
在这里插入图片描述
这里rdx在前面已经做过加操作,所以不会操作空指针,问题出在rcx或是rax身上。这里与之前通过查看代码判断问题是dio或是sg指针的结论一致。
继续往下看。找到离出错指令最近的rax和rcx的赋值指令:
mov 0x30(%r13),%rax
mov 0x58(%r15),%rcx
r13寄存器在第一张截图上已说明,该寄存器是由rdi赋值。rdi寄存器保存的就是形参bio的数据。这一点我们可以通过后面的赋值语句来判断:
movzwl 0x60(%rdi),%ebx
addq $0x1,0x258(%rsi)
对照源码可以很容易知道这两句对应的是
在这里插入图片描述
同样可以验证我们的猜想,我们将bio的数据结构打出来
在这里插入图片描述
可以看到,bio 0x60偏移处的数据正是bi_vcnt。之前提过,通过看代码我们猜想如果这里的num是0,那么sg就会是空指针。这里可以进一步把bio的数据打出来以验证之前的猜想
在这里插入图片描述
我们只需指定结构体的内存地址就能打印其中的数据了,而r13寄存器的地址在之前的bt中已经打出来了。
那这里我们几乎可以判断sg的首地址就是由rcx记录。同样可以验证一下猜想
在这里插入图片描述
这里就能说明操作空指针确实是由sg引起,而导致sg为空的原因就是函数入参bio中的成员bi_vcnt为0。
最后我们将sg的数据打出来看一下,看下其是否无数据,这里已经知道sg保存在r15寄存器中,而r15寄存器的数据同样在bt中记录了。
在这里插入图片描述
可以看到,sg的值为0x0。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yasin墨染锦年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值