Linux Kernel Panic报错解决思路 && addr2line工具使用 && Kernel cut here && Tombstone 分析

(1)什么是Kernel Panic?

        panic是英文中是惊慌的意思,Linux Kernel panic正如其名,linux kernel不知道如何走了,它会尽可能把它此时能获取的全部信息都打印出来。有两种主要类型kernel panic:
1.hard panic(也就是Aieee信息输出);2.soft panic (也就是Oops信息输出)

(2)什么会导致Linux Kernel Panic

        只有加载到内核空间的驱动模块才能直接导致kernel panic,你可以在系统正常的情况下,使用lsmod查看当前系统加载了哪些模块。除此之外,内建在内核里的组件(比如memory map等)也能导致panic。

       常见Linux Kernel Panic报错内容:
Kernel panic-not syncing fatal exception in interrupt
kernel panic – not syncing: Attempted to kill the idle task!
kernel panic – not syncing: killing interrupt handler!
Kernel Panic – not syncing:Attempted to kill init !

(3)hard panic

        对于hard panic而言,最大的可能性是驱动模块的中断处理(interrupt handler)导致的,一般是因为驱动模块在中断处理程序中访问一个空指针(null pointer)。一旦发生这种情况,驱动模块就无法处理新的中断请求,最终导致系统崩溃。

        根据panic的状态不同,内核将记录所有在系统锁定之前的信息。因为kenrel panic是一种很严重的错误,不能确定系统能记录多少信息,下面是一些需要收集的关键信息:

a,/var/log/messages: 幸运的时候,整个kernel panic栈跟踪信息都能记录在这里。要确认是否有一个足够的栈跟踪信息,你只要查找包含”EIP”的一行,它显示了是什么函数和模块调用时导致panic。
b,终端屏幕dump信息,一般OS被锁定后,复制,粘贴肯定是没戏了,因此这类信息,你可以需要借助拍照了。

(4)soft panic
        症状:没有hard panic严重,通常导致段错误(segmentation fault),可以看到一个oops信息,/var/log/messages里可以搜索到’Oops’,机器稍微还能用(但是收集信息后,应该会重启系统)。

        原因:凡是非中断处理引发的模块崩溃都将导致soft panic。在这种情况下,驱动本身会崩溃,但是还不至于让系统出现致命性失败,因为它没有锁定中断处理例程。导致hard panic的原因同样对soft panic也有用(比如在运行时访问一个空指针)。

(5)fatal exception

        “致命异常(fatal exception)表示一种例外情况,这种情况要求导致其发生的程序关闭。通常,异常(exception)可能是任何意想不到的情况(它不仅仅包括程序错误)。致命异常简单地说就是异常不能被妥善处理以至于程序不能继续运行。
        软件应用程序通过几个不同的代码层与操作系统及其他应用程序相联系。当异常(exception)在某个代码层发生时,为了查找所有异常处理的代码,各个代码层都会将这个异常发送给下一层,这样就能够处理这种异常。如果在所有层都没有这种异常处理的代码,致命异常(fatal exception)错误信息就会由操作系统显示出来。这个信息可能还包含一些关于该致命异常错误发生位置的秘密信息(比如在程序存储范围中的十六进制的位置)。这些额外的信息对用户而言没有什么价值,但是可以帮助技术支持人员或开发人员调试程序。

        当致命异常(fatal exception)发生时,操作系统没有其他的求助方式只能关闭应用程序,并且在有些情况下是关闭操作系统本身。

(6)安装linux系统遇到安装完成之后,无法启动系统出现Kernel panic-not syncing fatal exception。很多情况是由于板载声卡、网卡、或是cpu 超线程功能(Hyper-Threading )引起的。这类问题的解决办法就是先查看错误代码中的信息(诸如cut here,Modules linked in,PC is at,LR is at,Unable to handle kernelNULL pointer ),找到错误所指向的硬件,将其禁用。系统启动后,安装好相应的驱动,再启用该硬件即可(针对linux桌面系统)。

(7)针对嵌入式ARM和linux安卓等系统,有专门的分析方法和思路,比如针对:AEE HWT

参见:手机重启问题快速分析定位指南https://blog.csdn.net/zhandoushi1982/category_668701.html

===================addr2line工具使用============

        使用addr2line工具,有助于我们对内核崩溃现场进行分析,找到崩溃的文件和代码函数。

(1)先实验函数名对应的地址,再验证通过地址解析出函数名和行数

参见http://blog.csdn.net/whz_zb/article/details/7604760

(2)通过内核崩溃PC找到出错函数实例,比如如下崩溃字段:可以看到程序计数器PC是0xc03214cc。

(171012_20:25:54.609)PC is at __spi_sync+0x34/0x98
(171012_20:25:54.609)LR is at __spi_sync+0x20/0x98
(171012_20:25:54.609)pc : [<c032154c>]    lr : [<c0321538>]    psr: 600d0113
(171012_20:25:54.609)sp : ce6a3e08  ip : ce6a3e18  fp : 00000005
(171012_20:25:54.609)r10: 0000b4a8  r9 : dfcc7030  r8 : 00000030
(171012_20:25:54.609)r7 : 00000000  r6 : 00000000  r5 : 00000036  r4 : ce6a3e80
(171012_20:25:54.668)r3 : c0321404  r2 : ffffffd0  r1 : 00000000  r0 : ce6a3e08
(171012_20:25:54.669)Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
(171012_20:25:54.669)Control: 10c5387d  Table: 0d27c06a  DAC: 00000055
(171012_20:25:54.669)PC: 0xc03214cc:

找到对应内核的vmlinux二进制符号库(大概125M),然后执行如下命令,其中-e 选项来指定可执行映像。-f 选项,可以告诉工具输出函数名。

sw01@sw01-S2600CO:~/workspace/temp$ addr2line 0xc03214cc -e vmlinux -f
spi_async_locked

/home/sw01/workspace/fm1388/atc8317M/kernel/kernel-3.18/drivers/spi/spi.c:2064

(3)根据PC可以找到另一种处理方法

PC is at mali_sync_flag_signal+0x10/0x24 [mali]
LR is at mali_timeline_sync_fence_activate+0x18/0x34 [mali]
pc : [<bf6e3798>]    lr : [<bf6e25d0>]    psr: 600f0193
sp : c0c01e00  ip : 800f0193  fp : cdc25f00

r10: 00000000  r9 : 00000000  r8 : ca9ce480

PC最后指向mali_sync_flag_signal函数的0x10偏移;根据Mali.ko反汇编得到如下结果:

结合汇编代码可以看到是上图高亮的一句话,在将r1的内容写入r0+8的内存时发生寻址错误导致crash。

===============Kernel cut here====================================

Linux有时会提示cut here片段,类似内核崩溃但其实不是的栈LOG。比如:

[W]------------[ cut here ]------------
[W]WARNING: CPU: 1 PID: 1 at /home/sw01/workspace/fm1388/atc8317M/kernel/kernel-3.18/drivers/base/core.c:551 device_create_file+0x68/0x88()
Attribute fm1388_addr: read permission without 'show'
Modules linked in: i2c_fm1388(+) wlan_gen3 mtk_wmt_wifi mtk_stp_gps mtk_stp_bt mtk_stp_sdio mtk_stp_uart mtk_stp_wmt mtk_hif_sdio e52241_charger input drvcli(P) dvpagent i2c_dev gt9xx gps_6630 sonix_uvcvideo mali ump gdec pdec mtz_drv jdec imgcommon(P) avin videobuf_dma_contig videobuf2_dma_contig videobf2_vmalloc videobuf2_memops videobuf2_core videobuf_core mhldrv vdec drvdmx drvmmisc tvd wch adec drvstc backcar dualarmdrv fb1 atcfb vcp gfx irtdma imgresz [last unloaded: mtk_wmt_detect]
CPU: 1 PID: 1 Comm: init Tainted: P               3.18.0+ #23

[<c0015eb0>] (unwind_backtrace) from [<c0012414>] (show_stack+0x10/0x14)
[<c0012414>] (show_stack) from [<c067cf14>] (dump_stack+0x7c/0xd0)
[<c067cf14>] (dump_stack) from [<c0029370>] (warn_slowpath_common+0x64/0x84)
[<c0029370>] (warn_slowpath_common) from [<c0029410>] (warn_slowpath_fmt+0x2c/0x3c)

        从中可以明显看出提示点“Attribute fm1388_addr: read permission without 'show'”,解决完这个提示即可恢复,不再有这种提示。

===============Tombstone的分析====================================

        当一个动态库(native 程序)开始执行时,系统会注册一些连接到 debuggerd 的 signal handlers,当系统 crash 的时候,会保存一个 tombstone 文件到/data/tombstones目录下(Logcat中也会有相应的信息),文件的确就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程号,线程号),死亡的地址(在哪个地址上发生了 Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等。

        Tombstone的组成以及怎么分析tombstone文件,另外还有些分析工具(1)addr2line,上文已讲,(2)ndk-stack。参见网文:https://www.cnblogs.com/CoderTian/p/5980426.html


参考原文:http://www.ixpub.net/thread-759651-1-1.html
参考原文:http://hi.baidu.com/xysoul/blog/item/d85ebff2c2f1bc1bb17ec562.html

参考原文:http://blog.51osos.com/linux/linux-kernel-panic/ 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的 Linux kernel panic 堆栈信息解析示例: ``` Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [<c0102a9e>] (unwind_backtrace+0x0/0xe8) from [<c042f8f6>] (panic+0x64/0x13c) [<c042f8f6>] (panic+0x64/0x13c) from [<c042d7c2>] (do_exit+0x5fe/0x602) [<c042d7c2>] (do_exit+0x5fe/0x602) from [<c0101e80>] (die+0x20c/0x214) [<c0101e80>] (die+0x20c/0x214) from [<c0113a98>] (__do_kernel_fault.part.3+0x5c/0x84) [<c0113a98>] (__do_kernel_fault.part.3+0x5c/0x84) from [<c0113b88>] (do_page_fault+0x2a0/0x2b8) [<c0113b88>] (do_page_fault+0x2a0/0x2b8) from [<c0100e6e>] (do_DataAbort+0x34/0x98) [<c0100e6e>] (do_DataAbort+0x34/0x98) from [<c0102d24>] (__dabt_svc+0x44/0x60) ---[ end trace 5a7926b607e5b2d5 ]--- ``` 这个堆栈信息表示系统发生了一个 kernel panic,导致系统无法正常运行。下面是对每一行的解析: - 第一行是 kernel panic 的描述信息,告诉我们出现了什么问题。 - 第二行中的 `<c0102a9e>` 表示函数 `unwind_backtrace` 在代码中的位置,`0x0/0xe8` 表示函数内部的偏移量。这个函数是用来跟踪函数调用栈的,可以帮助我们定位问题发生的位置。 - 第三行中的 `<c042f8f6>` 表示函数 `panic` 在代码中的位置,`0x64/0x13c` 表示函数内部的偏移量。这个函数会导致系统进入 panic 模式,因此我们需要关注它。 - 第四行中的 `<c042d7c2>` 表示函数 `do_exit` 在代码中的位置,`0x5fe/0x602` 表示函数内部的偏移量。这个函数是用来退出进程的,可能与问题有关。 - 第五行中的 `<c0101e80>` 表示函数 `die` 在代码中的位置,`0x20c/0x214` 表示函数内部的偏移量。这个函数是用来输出错误信息和导致系统进入 panic 模式的,因此我们需要关注它。 - 第六行中的 `<c0113a98>` 表示函数 `__do_kernel_fault.part.3` 在代码中的位置,`0x5c/0x84` 表示函数内部的偏移量。这个函数是用来处理页面故障的,可能与问题有关。 - 第七行中的 `<c0113b88>` 表示函数 `do_page_fault` 在代码中的位置,`0x2a0/0x2b8` 表示函数内部的偏移量。这个函数也是用来处理页面故障的,可能与问题有关。 - 第八行中的 `<c0100e6e>` 表示函数 `do_DataAbort` 在代码中的位置,`0x34/0x98` 表示函数内部的偏移量。这个函数是用来处理数据异常的,也可能与问题有关。 - 最后一行表示跟踪结束的信息,可以忽略。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值