crash、kdump工具学习

kdump文档

制作initrd.img

https://blog.csdn.net/qq_26884501/article/details/112311201

find . | cpio --quiet -H newc -o | gzip -9 -n > /data/boot/initrd.img

调试运行中的linux

crash vmlinux
或者
crash /dev/mem vmlinux
或者
crash /proc/kcore vmlinux

触发

echo 1 > /proc/sys/kernel/sysrq
echo c > /proc/sysrq-trigger

crash命令学习

使用案例:

这里是基于8.0版本的crash编译的:

  • x86_64
  • ARM64
    • 此外,可以使用make target=ARM64可以编译出在x86上运行的用来解析ARM64架构的kdump文件的可执行程序,具体可以参考README
命令 用途 链接
bt 分析调用栈 https://www.cnblogs.com/pengdonglin137/p/16046329.html
dis 反汇编 https://www.cnblogs.com/pengdonglin137/p/16046333.html
struct 查看结构体信息 https://www.cnblogs.com/pengdonglin137/p/16064191.html
list 遍历链表 https://www.cnblogs.com/pengdonglin137/p/16046328.html
kmem 查看内核内存使用信息 https://www.cnblogs.com/pengdonglin137/p/16064197.html
task 查看任务的task_struct内容 https://www.cnblogs.com/pengdonglin137/p/16064200.html
vm 查看进程用户虚拟地址空间 https://www.cnblogs.com/pengdonglin137/p/16064189.html
ps 查看系统中存在着的进程 https://www.cnblogs.com/pengdonglin137/p/16064262.html
sys https://www.cnblogs.com/pengdonglin137/p/16064282.html
log 查看内核log https://www.cnblogs.com/pengdonglin137/p/16322568.html
rd 读取指定地址的内容 https://www.cnblogs.com/pengdonglin137/p/16332092.html
wr 将数字写入指定的地址 https://www.cnblogs.com/pengdonglin137/p/16332186.html
irq 查看系统中断统计信息,亲和性、软中断等 https://www.cnblogs.com/pengdonglin137/p/16322596.html
p 查看内核符号的值,支持percpu变量 https://www.cnblogs.com/pengdonglin137/p/16323246.html
ptov 将物理地址或者percpu地址转换为内核虚拟地址 https://www.cnblogs.com/pengdonglin137/p/16321489.html
vtop 将内核或者用户虚拟地址转换为物理地址,或者swap以及文件信息 https://www.cnblogs.com/pengdonglin137/p/16322393.html
runq 查看cpu运行队列 https://www.cnblogs.com/pengdonglin137/p/16064255.html
files 查看进程打开的文件 https://www.cnblogs.com/pengdonglin137/p/16064219.html
tree 遍历内核里的树结构体,比如红黑树、B树 https://www.cnblogs.com/pengdonglin137/p/16064232.html
waitq 查看在等待队列中睡眠的进程 https://www.cnblogs.com/pengdonglin137/p/16332333.html
whatis 查看内核符号或者数据类型的定义,以及查找特定的数据结构 https://www.cnblogs.com/pengdonglin137/p/16323402.html
search 在内存里搜索指定的内容 https://www.cnblogs.com/pengdonglin137/p/16320758.html
union
mach 查看物理地址布局、cpu硬件信息以及机器信息 https://www.cnblogs.com/pengdonglin137/p/16322503.html
ascii 将一串16进制数转换为ascii码 https://www.cnblogs.com/pengdonglin137/p/16322623.html
dev 查看设备节点信息,IO端口信息,磁盘统计 https://www.cnblogs.com/pengdonglin137/p/16322539.html
extend
foreach 遍历特定的进程并执行命令 https://www.cnblogs.com/pengdonglin137/p/16323260.html
set
sym 查看内核及模块的符号及地址 https://www.cnblogs.com/pengdonglin137/p/16332455.html
swap 查看交换设备使用信息 https://www.cnblogs.com/pengdonglin137/p/16322483.html
timer
sig
repeat 周期执行某个命令 https://www.cnblogs.com/pengdonglin137/p/16322524.html
net
mod 查看内核模块 https://www.cnblogs.com/pengdonglin137/p/16332526.html
mount 查看被挂载的文件系统信息 https://www.cnblogs.com/pengdonglin137/p/16322619.html
gdb
ipcs
fuser 查看一个文件正在被哪些进程使用 https://www.cnblogs.com/pengdonglin137/p/16322454.html
eval
pte 将pte表项转换为人可读的形式 https://www.cnblogs.com/pengdonglin137/p/16322440.html
btop/ptob 页帧号跟物理地址之间的转换 https://www.cnblogs.com/pengdonglin137/p/16322415.html
bpf
alias
sbitmapq
* 代替struct或者union https://crash-utility.github.io/help_pages/pointer.html

常用到的一些命令

  • 根据percpu的偏移量获取它的虚拟地址
    ptov <偏移量>:0,2,4-6
    然后就可以使用rd获取percpu变量在指定cpu上的值了。

系统宕机分析

熟练使用crash工具,对于分析系统异常宕机非常有帮助.当使用crash工具大致定位代码位置后,可以看一下跟新版的内核这块的有没有代码差异,如果有的话,可以用git blame等命令查看一部分的提交记录,可能社区已经有修复同一个问题的patch了。

系统宕机的原因大致有如下几种:

  1. 访问了非法内存: 如果开启了Kasan的话,当遇到内存OOB以及UAF等问题时,也会宕机
  2. 死锁导致进程处于不可中断状态的时间过长,此时如果配置了/proc/sys/kernel/hung_task_panic为1,那么系统会panic
  3. 在关闭了内核抢占的情况下,如果开启了softlockup宕机,那么当进程长时间运行在内核空间的话,也会导致宕机

非法内存访问

结合发生异常的调用栈、异常时的cpu寄存器上下文信息、源码以及反汇编来分析。

死锁

  1. 可以通过foreach UN bt -sx来遍历系统中所有处于D状态的进程,并将每个D状态的进程的调用栈打印出来
  2. 对于锁或者信号量的分析:
    • 如果是互斥锁,要找到当前谁持有这个锁以及哪些进程正阻塞在这个锁上比较容易。mutex.owner成员会记录当前正持有这把锁的进程的task_struct,由于地址对齐的原因,task_struct指针的低3位是空闲的,所以mutex会利用低3位来做一些其他工作。所以需要将owner的低3位屏蔽掉就可以获得谁持有这个互斥锁。

      bit 含义
      0 MUTEX_FLAG_WAITERS 表示锁的等待队列是否位空,即此时是否已经有进程阻塞在这个锁上了
      1 MUTEX_FLAG_HANDOFF 在释放互斥锁的时候,需要将锁的owner赋值为等待队列中的第一个进程
      2 MUTEX_FLAG_PICKUP

      获取被阻塞的进程:list -O mutex.wait_list -o mutex_waiter.list -s mutex_waiter.task -h <mutex结构的虚地址>

    • 对于读写信号量又可以分为普通的读写信号量,以及percpu的读写信号量,比较麻烦一些。

      • 如果是普通的读写信号量:
        • 获取写者:
        • 获取读者:可以使用search <锁地址>在进程的内核栈里搜索,然后逐个分析。
        • 获取被阻塞的进程:
      • 如果是percpu读写信号量
        • 获取写着:
        • 获取读者:可以使用search <锁地址>在进程的内核栈里搜索,然后逐个分析。
        • 获取被阻塞的进程:
    • 对于读写锁

进程相关

获取某个进程在cpu上运行了多长时间:

posted @ 2021-10-17 13:11  摩斯电码  阅读(739)  评论(0编辑  收藏  举报