[MTK] crash使用教程

文摘 Kernel MediaTek 2020-10-24 阅读:9978

什么是Crash?

当linux系统内核发生崩溃的时候,可以通过KEXEC+KDUMP等方式收集内核崩溃之前的内存,生成一个转储文件vmcore。内核开发者通过分析该vmcore文件就可以诊断出内核崩溃的原因,从而进行操作系统的代码改进。那么Crash就是一个被广泛使用的内核崩溃转储文件分析工具。
对调试来讲,gdb是非常适合的,但gdb始终是调试native的工具,不支持kernel信息显示,比如task信息之类的。crash补足了这个短板,由Dave Anderson开发和维护的一个内存转储分析工具,是基于GDB开发的 (GDB适用于用户进程的coredump,而Crash扩展了GDB,使其适用于linux kernel coredump),目前它的最新版本是7.2.3。在没有统一标准的内存转储文件的格式的情况下,Crash工具支持众多的内存转储文件格式,包括:

  1. Live linux系统
  2. kdump产生的正常的和压缩的内存转储文件
  3. 由makedumpfile命令生成的压缩的内存转储文件
  4. 由Netdump生成的内存转储文件
  5. 由Diskdump生成的内存转储文件
  6. 由Kdump生成的Xen的内存转储文件
  7. IBM的390/390x的内存转储文件
  8. LKCD生成的内存转储文件
  9. Mcore生成的内存转储文件

而MTK在KE时会抓取full dump文件:SYS_COREDUMP,则可以用crash来调试。

参考

Crash工具主页
使用 Crash 工具分析 Linux dump 文件
github上的crash
Analyzing Linux kernel crash dumps with crash - The one tutorial that has it all

安装/使用方法

crash是开源工具,因此需要自己下载代码编译成linux可执行文件。
请参考:【FAQ13939】搭建crash分析kernel ramdump平台

启动

    根据前面的文章,我们已经自己编译了crash可执行程序,共2个,一个是调试ARM的,一个是ARM64的,看你要调试的target是ARM还是ARM64,再决定用哪个。这里我将调试ARM的crash命名为crash,将调试ARM64的命名为crash64。

    启动crash需要2样东西,一个是vmlinux,一个是coredump,这里是SYS_COREDUMP。将vmlinux和SYS_COREDUMP放入crash可执行程序的同一目录中,启动ARM64的启动命令为:

  • ./crash64 vmlinux SYS_COREDUMP
  • 结果如下:

crash1.png

  • 这时就可以输入各种调试命令了。

常用命令

crash使用gdb作为它的内部引擎,crash中的很多命令和语法都与gdb相同。如果曾经使用过gdb,就会发现crash并不是很陌生。如果想获得crash更多的命令和相关命令的详细说明,可以使用crash的内部命令help来获取:

命令说明例子
*指针的快捷方式,用于代替struct/union*page 0xc02943c0:显示0xc02943c0地址的page结构体
files 显示已打开的所有文件的信息 files 462:显示进程462的已打开文件信息
mach 显示与机器相关的参数信息 mach:显示CPU型号,核数,内存大小等
sys 显示特殊系统的数据 sys config:显示CONFIG_xxx配置宏状态
timer 无参数。按时间的先后顺序显示定时器队列的数据 timer:显示详细信息
mod 显示已加载module的详细信息 mod:列出所有已加载module信息
runq 显示runqueue信息 runq:显示所有runqueue里的task
tree 显示基数树/红黑树结构 tree -t rbtree -o vmap_area.rb_node vmap_area_root:显示所有红黑树vmap_area.rb_node节点地址
fuser 显示哪些task使用了指定的文件/socket fuser /usr/lib/libkfm.so.2.0.0:显示使用了该文件的所有进程
mount显示已挂载的文件系统信息mount:当前已挂载的文件系统信息
ipcs显示System V IPC信息ipcs:显示系统中System V IPC信息
ps显示进程状态ps:类似ps命令
struct显示结构体的具体内容struct vm_area_struct c1e44f10:显示c1e44f10结构
union显示联合体的具体内容,用法与struct一致union bdflush_param:显示bdflush_param结构
waitq列出在等待队列中的所有task。参数可以指定队列的名称、内存地址等waitq buffer_wait:显示buffer_wait等待队列信息
irq显示中断编号的所有信息irq 18:显示中断18的信息
list显示链表的内容list task_struct.p_pptr c169a000:显示c169a000地址所指task里p_pptr链表
log显示内核的日志,以时间的先后顺序排列log -m:显示kernel log
dev显示数据关联着的块设备分配,包括端口使用、内存使用及PCI设备数据dev:显示字符/块设备相关信息
sig显示一个或者多个task的signal-handling数据sig 8970:显示进程8970的信号处理相关信息
task显示指定内容或者进程的task_struct的内容task -x:显示当前进程task_struct等内容
swap无参数。显示已配置好的交换设备信息swap:交换设备信息
search在给定范围的用户、内核虚拟内存或者物理内存搜索值search -u deadbeef:在用户内存搜索0xdeadbeef
bt显示调用栈信息bt:显示当前调用栈
net显示各种网络相关的数据net:显示网络设备列表
vm显示task的基本虚拟内存信息vm:类似于/proc/self/maps
btop把一个16进制地址转换成它的分页号N/A
ptob该命令与btop相反,是把一个分页号转换成地址N/A
vtop显示用户或内核虚拟内存所对应的物理内存N/A
ptov该命令与vtop相反。把物理内存转换成虚拟内存N/A
pte16进制页表项转换为物理页地址和页的位设置N/A
alias显示或建立一个命令的别名alias kp kmem -p:以后用kp命令相当于kmem -p
foreach用指定的命令枚举foreach bt:显示所有进程的调用栈
repeat循环执行指定命令repeat -1 p jiffies:每个1s执行p jiffies
ascii把16进制表示的字符串转化成ascii表示的字符串ascii 62696c2f7273752f:结果为/usr/lib
set设置要显示的内容,内容一般以进程为单位,也可以设置当前crash的内部变量set -p:切换到崩溃进程的上下文环境
pprint的缩写,打印表达式的值。表达式可以为变量,也可以为结构体N/A
disdisassemble的缩写。把一个命令或者函数分解成汇编代码dis sys_signal:反汇编sys_signal函数
whatis搜索数据或者类型的信息whatis linux_binfmt:显示linux_binfmt结构体
eval计算表达式的值,及把计算结果或者值显示为16、10、8和2进制N/A
kmem显示当前kernel使用内存状况kmem -i:显示kernel使用内存状况
sym显示符号所在的虚拟地址,或虚拟地址对应的符号sym jiffies:显示jiffies地址
rd显示指定内存的内容。缺少的输出格式是十六进制输出rd -a linux_banner:显示linux_banner内容
wr根据参数指定的写内存。在定位系统出错的地方时,一般不使用该命令wr my_debug_flag 1:修改my_debug_flag值为1
gdb执行GDB原生命令gdb help:执行gdb的help命令
extend动态装载或卸载crash额外的动态链接库N/A
q退出N/A
exit同q,退出N/A
help帮助命令N/A

扩展命令

crash支持扩展命令,具体请看crash扩展命令说明

其中有2个命令有助于分析问题:

命令说明例子
trace导出ftracetrace show > FTRACE:导出ftrace到FTRACE文件
gcore导出user process coredumpgcore -f 255 1:导出init进程的coredump

使用扩展命令前,需要先编译好对应的so库,下面介绍如何编译扩展命令的库。
编译扩展命令库
在官网扩展命令网站上下载对应的源码,放入crash源码里的extensions目录,比如将trace.c放入extensions目录。然后在crash源码目录下输入如下命令:
make extensions
编译好后,就有so库生成,文件放在extensions目录,比如trace.so。

扩展命令

    crash支持扩展命令,具体请看crash扩展命令说明

其中有2个命令有助于分析问题:

命令说明例子
trace导出ftracetrace show > FTRACE:导出ftrace到FTRACE文件
gcore导出user process coredumpgcore -f 255 1:导出init进程的coredump

使用扩展命令前,需要先编译好对应的so库,下面介绍如何编译扩展命令的库。

编译扩展命令库

官网扩展命令网站上下载对应的源码,放入crash源码里的extensions目录,比如将trace.c放入extensions目录。然后在crash源码目录下输入如下命令:

make extensions

编译好后,就有so库生成,文件放在extensions目录,比如trace.so。

crash2.png

使用扩展命令

进入crash后,在crash命令行添加扩展

extend <path-to>/xxx.so

crash3.png

crash即可支持对应的命令了。

0条评论

© 2024 芯缘异码. Powered by Typecho