红帽Linux故障定位技术详解与实例(2)

2011-09-28 14:26 圈儿 BEAREYES.COM 我要评论(0) 字号:T | T

在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行各种操作命令或测试程序的方式对故障环境进行观察,分析,测试,以定位出故障发生的原因。

AD:2014WOT全球软件技术峰会北京站 课程视频发布

3、内核故障情形及处理

(1)内核panic

panic是内核最直接的故障定位报告,发生panic时,内核已经认为故障定位已经导致操作系统不再具备正常运行的条件了. 当发生panic时,Linux会将所有CPU的中断和进程调度功能都关掉,所以这时系统是没有任何反应的,如果用户启动的是图形界面,则在屏幕上也看不到任何关于panic的信息.

我们通常遇到的,机器没反应,ping不通的情况,绝大部分都是panic. Panic发生时,内核直接在console上打印导致panic的代码位置的调用堆栈, 传统的用户用串口连接到机器上来收集console上的打印信息, 但串口这种方式,显然用起来不方便, 现在的Linux, 如RHEL5,RHEL6, 都采用kdump的方法来收集panic时的信息. 在配置好kdump的情况下,panic时系统会用kexec加载并切换到一个新的内核上(放置在预先分配的内存位置),并用磁盘或网络等将系统的全部或部分内存数据保存起来.

用kdump收集到panic的数据后,用户用crash工具就能直接查看导致panic的代码路径.

panic一般是很直观的,panic的堆栈信息能直接反映出导致bug的原因,如MCE故障,NMI故障, 数据结构分配失败等. 但有时panic是因为内核主动发现了关键的数据结构不一致性,这种不一致性是什么时候,什么代码导致的,并不清楚,可能还需要多次测试用SystemTap这样的工具进行捕捉

(2)多处理机环境内核执行路径产生的死锁

内核死锁和panic不一样,产生死锁时,内核并不主动的使自己处于挂起状态. 但内核死锁发生时,两个以上的CPU的执行路径在内核态不能推进了,处于互相阻塞状态, 而且是100%的占用CPU(用的spin-lock),直接或间接的导致全部CPU上的进程无法调度. 内核死锁又分两种情况:

- 涉及到中断上下文的死锁. 这种情况的死锁,最少一个CPU上的中断被屏蔽了.系统可能没法响应ping请求. 由于有一个CPU已经没法响应中断,其上的local APIC定时中断没法工作,可以用NMI Watchdog的方法来检测出来(检查local APIC handler维护的计数器变量),NMI Watchdog可以在其处理程序中调用panic(), 用户就可以用kdump收集内存信息,从而分析各死锁CPU上的调用堆栈,查处导致死锁的逻辑原因.

- 不涉及中断上下文的死锁. 这种情况的死锁,各CPU上的中断都是正常的,系统能对ping请求作出反应,这时NMI Watchdog无法被触发. 在 2.6.16之前的内核中,并没有一种很好的方法来处理这种情形. 在RHEL5, RHEL6 内核中, 每个CPU上提供了一个watchdog内核线程,在死锁出现的情况下,死锁CPU上的watchdog内核线程没法被调度(即使它是最高优先级的实时进程),它就没法update相应的counter变量,各CPU的NMI Watchdog中断会周期性的检查其CPU对应的counter, 发现没有updated, 会调用panic(),用户就可用kdump收集内存信息,分析各死锁CPU上的调用堆栈,查处导致死锁的逻辑原因.

(3)内核的oops或warning

oops 和warning和panic类似的地方是,他们都是因内核发现了不一致而主动报告的异常. 但oops和warning导致的问题严重程度要比panic轻很多,以致于内核处理该问题时不需要使系统挂起. 产生oops和warning, 内核通常已经在dmesg中记录了相当的信息,特别是oops, 至少会打印出现故障的地方的call trace. Oops也可转换成panic/kdump来进行offline-debugging, 只要将/proc/sys/kernel下的panic_on_oops变量设置为1就行了.

产生oops和warning的直接原因有很多,如内核中的segment fault, 或内核发现的某数据结构的counter值不对, 而segment fault 和counter值的变化还有更深层次的原因,通常并不能从内核dmesg的信息中看出来,解决这种问题的是要用SystemTap进行probe, 如发现某counter的值不对,就用SystemTap做一个probe来记录所有代码对该counter的访问, 然后再进行分析.

定位oops和warning会比定位应用程序的内存访问故障定位困难很多,因为在内核并不能象用valgrind去trace应用程序一样跟踪数据结构的分配和使用情况.

2、其他(硬件相关)故障

机器自动重启是一种常见的故障情形,一般是由硬件如物理内存故障引起的,软件的故障只会导致死锁或panic, 内核中几乎没有代码在发现问题的情况下去reboot机器. 在/proc/sys/kernel目录下有个参数“panic”, 其值如果设置为非0,则在panic发生若干秒后,内核会重启机器. 现在高端的PC服务器,都在努力用软件来处理物理内存故障,如MCA的 “HWPoison”方法会将故障的物理页隔离起来,Kill掉故障页所在的进程就可以了,RHEL6现在已经支持 “HWPoison”. 那些不具备MCA能力的机器,物理内存故障时,不会产生MCE异常,直接由硬件机制reboot机器

4、RHEL6 上的Debugging技术介绍

(1)Kdump故障定位收集和crash分析

kdump就是用来在内核panic的情况下收集系统内存信息的, 用户也可在online情况下用sysrq的'c'键触发. Kdump 采用没有污染的内核来执行dump工作,所以其比以前的diskdump, lkcd方法更可靠. 使用kdump,用户可选择将数据dump到本地盘或网络上,也可通过定义makedumpfile的参数过滤要收集的内存信息,已减少kdump所需要的停机时间

Crash就是对kdump的信息进行分析的工具.其实际就是gdb的一个wrapper. 使用crash时,最好安装kernel-debuginfo包,这样能解析kdump收集的内核数据的符号信息. 用crash来定位问题的能力,完全取决于用户对内核代码的理解和分析能力

参考 “#>man kdump.conf”, “#>man crash”, “#>man makedumpfile”学习怎样使用kdump和crash. 访问 http://ftp.redhat.com可下载debuginfo文件

(2)用systemTap定位bug

systemtap 属于probe类的定位工具,它能对内核或用户代码的指定位置进行probe, 当执行到指定位置或访问指定位置的数据时,用户定义的probe函数自动执行,可打印出该位置的调用堆栈,参数值,变量值等信息. systemtap选择进行probe的位置很灵活,这是systemtap的强大功能所在. Systemtap的probe点可包括如下几个方面:

- 内核中全部系统调用,内核及模块中全部函数的入口或出口点

- 自定义的定时器probe点

- 内核中任意指定的代码或数据访问位置

- 特定用户进程中任意制定的代码或数据访问位置

- 各个功能子系统预先设置的若干probe点,如tcp,udp,nfs,signal各子系统都预先设置了很多探测点

systemTap的脚本用stap脚本语言来编写,脚本代码中调用stap提供的API进行统计,打印数据等工作,关于stap语言提供的API函数,参考 “#> man stapfuncs”. 关于systemTap的功能和使用可参考 “#> man stap”, “#> man stapprobes”

(3)ftrace

ftrace 是linux内核中利用tracepoints基础设施实现的事件追踪机制,它的作用在于能比较清楚的给出在一定时间内系统或进程所执行的活动,如函数调用路径,进程切换流等. Ftrace可用于观察系统各部分的latency,以便进行实时应用的优化; 它也可以通过记录一段时间内的内核活动来帮助故障定位. 如用以下方法可trace某个进程在一端时间的函数调用情况

  1. #> echo “function” > /sys/kernel/debug/tracing/current_tracer
  2. #> echo “xxx” > /sys/kernel/debug/tracing/set_ftrace_pid
  3. #> echo 1 > /sys/kernel/debug/tracing/tracing_enabled

除tracing函数调用外,ftrace还可tracing系统的进程切换,唤醒,块设备访问,内核数据结构分配等活动. 注意,tracing和profile是不同的,tracing记录的是一段时间内的全部活动,而不是统计信息,用户可以通过/sys/kernel/debug/tracing下的buffer_size_kb设置缓冲区的大小, 以记录更长时间的数据.

关于ftrace的具体使用可参考内核源码Documenation/trace下的内容

(4)oprofile 和 perf

oprofile和perf都是对系统进行profile(抽样,统计)的工具,它们主要用来解决系统和应用的性能问题. perf功能更强大,更全面,同时perf的用户空间工具和内核源码一起维护和发布,让用户能及时的享受perf内核新增加的特征. Perf 是在RHEL6中才有,RHEL5中没有Perf. Oprofile和perf 都使用现代CPU中具有的硬件计数器进行统计工作,但perf还可以使用内核中定义的 “software counter”及 “trace points”, 所以能做更多的工作. Oprofile的抽样工作利用 CPU的NMI中断来进行,而perf既可以利用NMI中断也可利用硬件计数器提供的周期性中断. 用户能很容易用perf来oprofile一个进程或系统的执行时间分布,如

  1. #> perf top -f 1000 -p

还可以利用系统定义的 “software counter”和各子系统的 “trace points” 对子系统进行分析, 如

  1. #>perf stat -a -e kmem:mm_page_alloc -e kmem:mm_page_free_direct -e kmem:mm_pagevec_free sleep 6

能统计6秒内kmem子系统的活动 (这一点实际是利用ftrace提供的tracepoints来实现)

我认为有了perf, 用户就没必要使用oprofile了

红帽Linux故障定位技术详解与实例(2)的更多相关文章

  1. 红帽Linux故障定位技术详解与实例(4)

    红帽Linux故障定位技术详解与实例(4)   在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行 ...

  2. 红帽Linux故障定位技术详解与实例(3)

    红帽Linux故障定位技术详解与实例(3)   在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行 ...

  3. 红帽Linux故障定位技术详解与实例(1)

    红帽Linux故障定位技术详解与实例(1) 2011-09-28 14:26 圈儿 BEAREYES.COM 我要评论(0) 字号:T | T 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍 ...

  4. Protocol Buffer技术详解(Java实例)

    Protocol Buffer技术详解(Java实例) 该篇Blog和上一篇(C++实例)基本相同,只是面向于我们团队中的Java工程师,毕竟我们项目的前端部分是基于Android开发的,而且我们研发 ...

  5. Protocol Buffer技术详解(C++实例)

    Protocol Buffer技术详解(C++实例) 这篇Blog仍然是以Google的官方文档为主线,代码实例则完全取自于我们正在开发的一个Demo项目,通过前一段时间的尝试,感觉这种结合的方式比较 ...

  6. Linux crontab命令详解与实例

    内容有重复的,不过本着宁多勿少的原则就都看看吧,就当加深印象啦 基本格式 :* * * * * command分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示第2列表示小时 ...

  7. kali Linux渗透测试技术详解

    kali Linux渗透测试技术详解 下载:https://pan.baidu.com/s/1g7dTFfzFRtPDmMiEsrZDkQ 提取码:p23d <Kali Linux渗透测试技术详 ...

  8. Python开发技术详解(视频+源码+文档)

    Python, 是一种面向对象.直译式计算机程序设计语言.Python语法简捷而清晰,具有丰富和强大的类库.它常被昵称为胶水语言,它能够很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松地联结 ...

  9. 手游录屏直播技术详解 | 直播 SDK 性能优化实践

    在上期<直播推流端弱网优化策略 >中,我们介绍了直播推流端是如何优化的.本期,将介绍手游直播中录屏的实现方式. 直播经过一年左右的快速发展,衍生出越来越丰富的业务形式,也覆盖越来越广的应用 ...

随机推荐

  1. 学习前端D1

    第一次写博客,有些小激动,以前写学习的记录都是在有道云笔记上写的,在博客园上更多的是膜拜大佬.偷师学艺.前段时间,我和朋友闲聊时,知道用博客每天写知识会提高学习的热情,这感情好呀,于是乎,今天,我依旧 ...

  2. C#4.0中的协变和逆变

    原文地址 谈谈.Net中的协变和逆变 关于协变和逆变要从面向对象继承说起.继承关系是指子类和父类之间的关系:子类从父类继承所以子类的实例也就是父类的实例.比如说Animal是父类,Dog是从Anima ...

  3. Xshell的使用以及常用命令

    工具/原料 Xshell 方法/步骤 打开软件,点击新建,在主机哪里写入要访问的ip地址,名称随意 点击文件之后,再点击打开: 就可以看到刚才新建的会话了: 点击连接,就会显示下面的画面,输入用户名, ...

  4. (转)C++ bitset用法

    今天做题发现要用到bitset,找到一篇介绍的巨好的文章. 转载自:https://www.cnblogs.com/magisk/p/8809922.html C++的 bitset 在 bitset ...

  5. HttpClient常用方法总结

    1.HttpPost发送表单请求 String url = ""; HttpPost httpPost = new HttpPost(url); List<NameValue ...

  6. (一)使用twisted Deferred

    一.开篇 为什么是twisted,twisted作为一个python网络编程框架,出道早,但一直不温不火,这几年和tornado比起来,更是近乎销声匿迹:但作为初学者,觉得twisted还是有很多优点 ...

  7. 2. zookeeper介绍及集群搭建

    ZooKeeper 概述 Zookeeper 是一个分布式协调服务的开源框架. 主要用来解决分布式集群中 应用系统的一致性问题,例如怎样避免同时操作同一数据造成脏读的问题. ZooKeeper 本质上 ...

  8. Storm本地启动拓扑报错:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/storm/topology/IRichSpout

    问题描述: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/storm/topology ...

  9. 【计算机网络】-介质访问子层-(信道划分介质访问控制&随机访问介质访问控制)

    [计算机网络]-介质访问子层-概述 介质访问控制子层功能 解决信道争用的协议,即用于多路访问信道上确定下一个使用者的协议 是数据链路层协议的一部分 介质访问控制子层位置 位于数据链路层的底部! 信道分 ...

  10. JS中的继承(下)

    JS中的继承(下) 在上一篇 JS中的继承(上) 我们介绍了3种比较常用的js继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...