linux打印调用栈 函数名_linux内核调试之 crash分析dump文件

Linux 下也有众多的内存转储分析工具,lcrash、Alicia、Crash。Crash 是由 Dave Anderson 开发和维护的一个内存转储分析工具,目前它的最新版本是 。 在没有统一标准的内存转储文件的格式的情况下,Crash 工具支持众多的内存转储文件格式:

  • Live linux 系统
  • kdump 产生的正常的和压缩的内存转储文件
  • 由 makedumpfile 命令生成的压缩的内存转储文件
  • 由 Netdump 生成的内存转储文件
  • 由 Diskdump 生成的内存转储文件
  • 由 Kdump 生成的 Xen 的内存转储文件

等等

【1】命令格式

crash [OPTION]... NAMELIST MEMORY-IMAGE[@ADDRESS]

1、namelist 是调试版本内核,即-g选项编译的,可以自己用源码加-g编译,可以到发行版网站下载kernel-debuginfo软件包,包含内核在/usr/lib/debug/lib/modules/内核版本/vmlinux;

2、memory-image 就是转存的某格式dump文件

【2】安装对应的kernel-debuginfo 和 软件包debug-info-common

可在对应发行版网址上下载安装包:这里以centos8为例:

debuginfo.centos.org/8/

rpm -ivh kernel=debuginfo-common-xxx.rpm
rpm -ivh kernel=debuginfo-xxx.rpm

【3】执行

crash /usr/lib/debug/lib/modules/4.18.0-193.19.1.el8_2.x86_64/vmlinux /var/crash/127.0.0.1-2020-10-27-03\:54\:42/vmcore

crash 命令提示符

【4】crash常用内部命令

通过 crash 的内部命令,可以查看寄存器的值、函数的调用堆栈等信息。crash 使用 gdb 作为它的内部引擎,crash 中的很多命令和语法都与 gdb 相同。

1、 bt

backtrace)打印内核堆栈,可以打印所以内核堆栈,也可以指定进程。

bt + pid 列出相应的进程堆栈

bt -f 会列出所有堆栈里面数据

bt -p 只打印panic的线程的内核栈,仅限于crash dump

2、dmesg(log)

查看崩溃时的log

3、dis

disassemble反汇编,参数可以使地址、符号(函数名、变量名),对其反汇编得到该地址对应的源码

对应源码:

第一行是ftrace的空指令;

第二、三、四、六行,是函数参数传递,rdi是第一个参数;

jmpq 是跳转到下一个函数地址:do_sys_open

另外 -l参数可以显示行号。

dis -l

dis -s [地址或符号] 显示源文件名和源码

dis -l write_sysrq_trigger+9 10 显示符号地址+偏移,共显示10行

4、rd

read memory. 读相应的内存。

5、mod

module。查看显示、加载模块符号调试信息。crash使用的调试内核vmliux不包含ko,所以调试内核模块需要加载-g编译后的ko里的符号信息。

1)mod 不再参数会显示当前系统安装的模块(以及加载符号)

2)mod -S 加载所有安装模块的符号调试信息

3)mod -s xxxmodule 加载指定安装模块的符号调试信息

4)mod -d xxxmodule

mod -s /tmp/xxx/xxxmodule 删除并重新加载指令路径的模块的符号调试信息

6、x/FMT

examine memory。FMT包含size、格式和长度,比如 x/16x 就是打印出16个四字节长度地址的数(默认四字节),以十六进制格式显示。

x/nfu
n表示要显示的内存单元的个数
f表示显示方式, 可取如下值
x 按十六进制格式显示变量。 d 按十进制格式显示变量。 u 按十进制格式显示无符号整型。 o 按八进制格式显示变量。 t 按二进制格式显示变量。 a 按十六进制格式显示变量。 i 指令地址格式 c 按字符格式显示变量。 f 按浮点数格式显示变量。
u表示一个地址单元的长度
b表示单字节, h表示双字节, w表示四字节, g表示八字节

和rd命令类似,只不过x是gdb的命令。

8、sym

虚拟地址和符号相互转换

和dis -s [地址] 效果差不多

9、ps

打印内核崩溃时,正常的进程信息

可以加pid查看指定进程状态

10、file

打印指定进程的文件打开列表(可配合ps使用)

类似的命令还有:

vm [pid] 进程虚拟地址空间

11、task [pid]

进程task_struct和thread_info的信息

12:kmen

可以查看当时的内存使用情况

kmem -I

【5】实际测试

(1)主动触发的例子

1、触发

echo c > /proc/sysrq-trigger

2、crash分析dump文件

(2)空指针产生的core dump文件

1、crash打开core dump 文件

crash /usr/lib/debug/lib/modules/4.18.0-193.19.1.el8_2.x86_64/vmlinux vmcore

2、bt -p 查看dump堆栈线程信息(或者dmesg或者log看内核dmesg信息)

3、分析

寄存器RIP是程序指令指针寄存器,可以看出在执行到proc_fork_connector 时触发了页异常。通过栈回溯打印,上一个函数是copy_process.

4、dis -s 分析源码里这个函数哪里来的

dis -s 0xffffffff846aff85

可见在copy_process 函数中,调用proc_fork_connector 崩溃,进而分析可能是参数p 有问题

实验环境:

内核版本:kernel 4.18.0-193.19.1.el8_2.x86_64

crash版本:crash version: 7.2.7-3.el8

kexec-tool:kexec-tools 2.0.20

【6】参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值