• 如何分析oops


    Linux kernel oops

    在Linux上,oops即Linux内核的行为不正确,并产生了一份相关的错误日志。许多类型的oops会导致内核错误,即使系统立即停止工作,但部分oops也允许继续操作,作为与稳定性的妥协。这个概念只代表一个简单的错误。
    当内核检测到问题时,它会打印一个oops信息然后杀死全部相关进程。oops信息可以帮助Linux内核工程师调试,检测oops出现的条件,并修复导致oops的程序错误
    Linux官方内核文档中提到的oops信息被放在内核源代码Documentation/oops- tracing.txt中。通常klogd是用来将oops信息从内核缓存中提取出来的,然而,在某些系统上,例如最近的Debian发行版 中,rsyslogd代替了klogd,因此,缺少klogd进程并不能说明log文件中缺少oops信息的原因。
    若系统遇到了oops,一些内部资源可能不再可用。即使系统看起来工作正常,非预期的副作用可能导致活动进程被终止。内核oops常常导致内核错误,若系统试图使用被禁用的资源。


    http://bbs.chinaunix.net/thread-686615-1-1.html

    看到有人贴出oops的消息不禁想了解一下在linux下大家是如何解决这类问题的。

    因为刚开始学习linux内核,所以也只是略知一二,现在就将我的了解说说:

    1. Oops是什么?

    看LKD对oops的描述,oops就应该是unix系统的system panic,叫法不同而已。

    什么是panic呢?简单的说就是内核程序错误引发的一种debug和保护机制,系统会dump出内核映像,里面包含了当时CPU的状态,进程的状态,内核堆,栈的状态...最直观的最重要的恐怕就是 调用栈的back trace.

    很多情况下,一个oops是可以被重现的,根据调用栈的back trace和printk也许就搞定了问题。
    但更多的时候,一个oops是很难重现,比如一个race condition.
    这时候,分析一个oops之后的crash dump文件就变得尤为重要了。

    2. 如何分析oops.

    分析panic的思路和分析应用程序coredump的思路一样的。

    首先,要看调用的backtrace和错误消息.

    看程序是在哪个函数产生发生了错误,看消息里面有什么有价值的信息,比如空指针引用之类的。


    其次,了解了backtrace在什么位置,就可以结合源代码来看是否有问题了。

    幸运的话,光看具体函数的代码也许就会发现问题。

    但多数时候,还需要检查crash dump的映像文件的。

    这时候,一个好用的帮助分析crash dump的工具就尤为重要了。

    在solaris下,我们可以通过mdb来查看panic时在CPU运行的所有线程的状态,

    CPU寄存器的状态,信号量,锁...
    因为IA32的特性,调用栈、backtrace里面每个函数的参数,都可以得到。
    此外还有堆的状态。

    通过以上这些数据,我们会试图重新描绘出系统崩溃那一刹那,发生了什么。


    在linux下,该如何做类似的分析工作呢?

    因为种种原因,linux至今没有集成kernel debug工具,但还是有一些第3方工具可用:

    1.kdb

    特点:二进制,汇编级的调试工具。只需要一台机器。


    2.kgdb

    特点:源代码级的调试工具,但需要两台机器,null modem线连接。

    局限:需要patch重新编译内核。而且,在事后分析crash dump文件的情况下,尤其是当oops不可重现时,只能在汇编和二进制下工作了。


    3.gdb

    特点:linux环境中自带

    局限:功能有限,但检查crash dump也许足够了。

    linus本人不提倡用kernel debug工具,那他们是如何检查一个crash dump文件的呢?我猜想是用gdb

    4.其它工具和方法...




    大家不妨谈谈自己学习和使用这些工具的心得,拿出知道的一些资料共享一下。





    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(804) | 评论(0) | 转发(1) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    【剑指Offer】跳台阶&变态跳台阶
    【剑指Offer】替换空格
    【剑指Offer】二维数组中的查找
    【Leetcode】2. Add Two Numbers 两数相加
    HTML学习笔记(一)HTML的一些概念区别
    C#项目中一些文件类型说明
    数据结构初步归纳(一)概念、线性表以及队列和栈
    线程相关概念
    程序开发方法论
    C#集合类型
  • 原文地址:https://www.cnblogs.com/ztguang/p/12648483.html
Copyright © 2020-2023  润新知