c++ dump某个变量_linux内核调试之 crash分析dump文件

发布于:2021-09-14 19:52:33

Linux 下也有众多的内存转储分析工具,lcrash、Alicia、Crash。Crash 是由 Dave Anderson 开发和维护的一个内存转储分析工具,目前它的最新版本是 5.0.0。 在没有统一标准的内存转储文件的格式的情况下,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为例:


http://debuginfo.centos.org/8/x86_64/Packages/











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】参考:


https://www.ibm.com/developerworks/cn/linux/l-cn-kdump3/index.html?mhsrc=ibmsearch_a&mhq=%E4%BD%BF%E7%94%A8%20Crash%20%E5%B7%A5%E5%85%B7%E5%88%86%E6%9E%90%20Linux%20dump%20%E6%96%87%E4%BB%B6?www.ibm.com

相关推荐

最新更新

猜你喜欢