Linux内核崩溃 dump调试

文章详细介绍了Linux系统中内核崩溃时出现的oops消息,包括其格式、内容和分析方法,如通过PC指针、寄存器和调用堆栈来定位错误。此外,还阐述了coredump的概念,当程序异常终止时如何生成和使用coredump文件进行调试,包括设置coredump大小、路径和使用gdb进行分析的步骤。
摘要由CSDN通过智能技术生成

内核-crash(崩溃),oops消息,dump

oops

(也称 panic),称程序运行崩溃,程序崩溃后会产生oops消息。

应用程序或内核线程的崩溃都会产生oops消息,通常发生oops时,系统不会发生死机,而在终端或日志中打印oops信息

内容有PC指针,CPU R0-R15寄存器和堆栈信息,崩溃前函数调用情况等

oops 的格式

  内核的文档里的详细的Oops的说明,的名字是

        Documentation/oops-tracing.txt

        http://www.mjmwired.net/kernel/Documentation/oops-tracing.txt

        Linux Kernel Documentation :: oops-tracing.txt (mjmwired.net)

oops第一段出错是内存page地址,

        例如提示,

        Unable to handle kernel NULL pointer dereference at virtual address 00000000

        往往表示碰到空指针了

第二段出错时是寄存器的快照,不同CPU显示不同情况;

     其中基本上所有CPU都会有的PC寄存器(Program counter register),它保存最后出问题的地址。
      LR保存着函数返回地址。这里就比较容易看出是谁出问题

最重要是第三段,即可出错的调用堆栈(Call Trace).从这里即可推算出错的所在函数

        [ 9054.949421] Call trace:

        [ 9054.951886]  w5500_write_buf+0x15c/0x1ac [w5500_wiz0]

        这告诉我们,w5500_write_buf函数有0x1ac 这么大,而Oops发生在0x15c处

        两个值指得都是汇编代码的值

反汇编定位

        把驱动编译过程文件xxx.o进行反汇编,现在Linux 自带的objdump生成.s文件

        aarch64-linux-objdump -d w5500-wiz0.o > driver.s

        在driver.s文件里找到对应的函数:

        0000000000000a50 <w5500_write_buf>:

        a68: a9b67bfd stp x29, x30, [sp, #-160]!

        ......

        bf8: d65f03c0 ret

        函数的基址为0xa68 出错行需加上偏移 0xa68+0x15c=0xbc4;

定位出错代码行:aarch64-linux-addr2line

          注意:在编译驱动的时候在Makefile中添加参数 “KBUILD_CFLAGS+= -g” 参数,导致使用addr2line工具时无法找到oops具体对应的行

aarch64-linux-addr2line -C -f -e w5500-wiz0.o bc4

w5500_write_buf

/home/forlinx/3568/atms/0_driver/w5500/dev.c:223 (discriminator 3)

coredump

/proc/sys/kernel

  查看系统是否生成 core dump文件

        ulimit -c   返回0表不生成  大于0的数表生成文件大小限制  unlimited表文件大小不受限制

设置core dump文件大小(命令设置是临时的,永久生效

        ulimit -c 0

        ulimit -c 1024

        ulimit -c unlimited

当程序运行过程中异常终止或崩溃时会发生 core dump

用 Core Dump 表示当程序异常终止或崩溃时,将进程此时的内存中的内容拷贝到磁盘文件中存储,以方便编程人员调试

下列出几种信号,它们在发生时会产生 core dump:

Signal

Action

Comment

SIGQUIT

Core

Quit from keyboard

SIGILL

Core

Illegal Instruction

SIGABRT

Core

Abort signal from abort

SIGSEGV

Core

Invalid memory reference

SIGTRAP

Core

Trace/breakpoint trap

当然不仅限于上面的几种信号。这就是为什么我们使用 Ctrl+z 来挂起一个进程或者 Ctrl+C 结束一个进程均不会产生 core dump,因为前者会向进程发出 SIGTSTP 信号,该信号的默认操作为暂停进程(Stop Process);后者会向进程发出SIGINT 信号,该信号默认操作为终止进程(Terminate Process)。同样 kill -9 命令会发出 SIGKILL 命令,该命令默认为终止进程。

而如果我们使用 Ctrl+\ 来终止一个进程,会向进程发出 SIGQUIT 信号,默认是会产生 core dump 的。还有其它情景会产生 core dump, 如:程序调用 abort() 函数、访存错误、非法指令等等。

设置core dump 文件存储路径及命名规则:

默认生成的 core 文件保存在可执行文件所在的目录下,文件名就为 core。

通过修改 /proc/sys/kernel/core_uses_pid 文件可以让生成 core 文件名是否自动加上 pid 号。

生成的 core 文件名将会变成 core.pid,其中 pid 表示该进程的 PID。

[root@atms:/proc/sys/kernel]# echo 1 > core_uses_pid                                                                    

还可以通过修改 /proc/sys/kernel/core_pattern 来控制生成 core 文件保存的位置以及文件名格式。

例如可以用 echo "/tmp/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern 设置生成的 core 文件保存在 “/tmp/corefile” 目录下,文件名格式为 “core-命令名-pid-时间戳”

%% 单个%字符
%p dump进程的进程ID
%u dump进程的用户ID
%g dump进程的组ID
%s 导致core dump的信号
%t core dump 的时间
%h 主机名
%e 程序文件名

[root@atms:/proc/sys/kernel]# ls core*  

core_pattern  core_pipe_limit  core_uses_pid

[root@atms:/proc/sys/kernel]# echo "/tmp/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern

使用 gdb 调试 Core 文件

主机(ubuntu)安装aarch64-linux-gdb

主机默认下只有x86的gdb,没有arm环境下的aarch64-linux-gdb

进入ok3568-linux-source/buildroot/output/OK3568目录下执行make menuconfig 搜索gdb

按1进入build cross gdb for the host 选中即可

返回ok3568-linux-sourc 执行 ./build.sh buildroot 完成后..../OK3568/host/bin 目录下会生成该工具

gdb调试coredump文件

产生了 core 文件,我们该如何使用该 Core 文件进行调试呢?Linux 中可以使用 GDB 来调试 core 文件,步骤如下:

首先,使用 gcc 编译源文件,加上 -g 以增加调试信息;

aarch64-linux-gcc test.c -o test -g

arm板打开 core dump 以使程序异常终止时能生成 core 文件;

        ulimit -c unlimited

        echo 1 > proc/sys/kernel/core_uses_pid

        echo "/tmp/corefile-%e-%p-%t" > /proc/sys/kernel/core_pattern

运行程序,当core dump 之后,使用命令 gdb [program] [core] 来查看 core 文件,其中 program 为可执行程序名,core 为生成的 core 文件名。

例:

[root@atms:/mnt/nfs]# ./test_core           

Segmentation fault (core dumped)  程序段错误

[root@atms:/mnt/nfs]# ls /tmp/core*

/tmp/corefile-test_core-15327-1677554939   在设定的tmp目录下生成对应的core 文件

将core 文件拷贝到主机,在主机上执行命令

aarch64-linux-gdb  test_core  corefile-test_core-15327-1677554939

指示出错位置行号及对应的代码;

bt命令,显示函数调用堆栈,显然func函数被main函数调用

 

f 0 或 f 1 命令,打印栈号0或1的堆栈,显示函数是怎么调用另一函数的 f全称 frame

可以看反汇编代码disass,cpu寄存器的值info reg等

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值