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

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

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

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

红帽Linux故障定位技术详解与实例是本文要介绍的内容,主要是来了解并学习红帽linux故障定位技术的学习,故障定位技术分为在线故障定位和离线故障定位,一起来看详解。

1、故障定位(Debugging)场景分类

为便于描述问题,将Linux上各种软件故障定位的情形分成两类

(1)在线故障故障定位

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

(2)离线故障定位

离线故障定位(offline-debugging)就是在故障发生时,故障所处的操作系统环境已经无法正常访问,但故障发生时系统的全部或部分状态已经被系统本身所固有或事先设定的方式收集起来,故障处理人员可通过对收集到的故障定位状态信息进行分析,定位出故障发生的原因

2、应用进程故障情形及处理

应用进程的故障一般不会影响操作系统运行环境的正常使用(如果应用代码的bug导致了内核的crash或hang,则属于内核存在漏洞),所以可采用在线故障定位的方法,灵活的进行分析. 应用代码故障的情形有如下几种:

(1)进程异常终止

很多用户认为进程异常终止情况无从分析,但实际上进程异常终止情况都是有迹可寻的. 所有的进程异常终止行为,都是通过内核发信号给特定进程或进程组实现的. 可分成几个类型进行描述:

- SIGKILL. SIGKILL最特殊,因为该信号不可被捕获,同时SIGKILL不会导致被终止的进程产生core文件, 但如果真正的是由内核中发出的SIGKILL,则内核一定会在dmesg中记录下信息. 另外在内核中使用SIGKILL的地方屈指可数,如oom_kill_process()中, 所以通过dmesg记录并且分析内核中使用SIGKILL的代码,并不难分析原因

- SIGQUIT, SIGILL, SIGABRT, SIGBUS, SIGFPE, SIGSEGV. 这几个信号在保留情况下会终止进程并会产生core文件, 用户根据core中的stack trace信息,能直接定位出导致终止信号的代码位置. 另外, SIGQUIT,SIGABRT一般是由用户代码自己使用的,好的代码一般会记录日志. SIGILL, SIGBUS, SIGFPE, SIGSEGV, 都是由内核中产生的,搜索内核源码,不难列出内核中使用这几个信号的地方, 如SIGILL 是非法指令,可能是浮点运算产生的代码被corrupted或文本区域的物理内存corruption; SIGBUS多由MCE故障定位导致; SIGSEGV多由应用代码的指针变量被corrupted导致. 对于应用的heap或stack的内存被corrupted, 可用valgrind工具对应用进行profile, 通常能直接发现导致corruption的代码

- SIGINT, SIGPIPE, SIGALRM, SIGTERM. 这几个信号在保留情况下终止进程但不会产生core文件. 对这几个信号,建议用户一定要定义一个handler,以记录产生问题的上下文. 比较容易忽略的是SIGPIPE, 很多用户程序在使用select()或poll()时只监听read/write描述符,不监听exception描述符,在对方TCP已经关闭的情况下,仍然向socket中写入,导致SIGPIPE.

- 对于恶意的代吗产生的进程终止行为,如合作的一些进程中,A向B发SIGKILL, 而没做日志记录,或者B直接判断某条件而调用exit(), 也没有做日志记录.在应用代码量很大的情况下,通过分析代码故障定位这种情形也许很难. SystemTap提供了解决这个问题的一个比较好的方法,就是写用户层的probes, 追踪进程对signal(), exit() 等系统调用的使用

(2)进程阻塞,应用无法正常推进

这种情况,对于单个被阻塞的进程而言,属于正常状态, 但对于包含多个进程的应用整体而言,属于异常. 应用无法推进,说明其中某一个进程推进的因素出现了问题,导致其他依赖于它的进程也要等待. 分析这种情形需要分析清楚进程或事件之间的依赖关系,及数据的处理流. 首先要用gdb -p 的back trace功能查出各进程阻塞的执行路径, 以确定每个进程所处在的状态机的位置.

通常而言,如果只考虑各个进程的状态,则进程之间可能形成了一种互相依赖的环形关系,如(P1发请求=>P2处理=>P2发反应=>P1再请求=>P2处理=>P2再发反应), 但应用对workload, 一般是按一个个的transaction 或 session的方式进行处理的,每个transaction都有起点和终点, 我们需要用strace, tcpdump 等工具以及应用的执行日志进行观察,分析出当前正被处理的transaction所被阻滞的位置,从而找出全部状态机被阻塞的原因. 导致这种状态机停止运转的原因有多个:如和应用通信的远端出现了问题,后端数据库/目录等出现了问题,应用的某个进程或线程处于非正常的blocking位置或直接终止,不再正常工作.

(3)用户进程形成死锁

用户进程形成死锁,如果没有内存上的故障定位,则完全是应用自身的逻辑问题. 死锁的进程或线程之间由于锁的互相占有形成了环路。 这种情况发生时,用gdb -p 的back trace的功能能直接确定死锁的进程全部阻塞在futex()等和锁相关的系统调用上, 这些调用futex()的路径可能是mutex, semaphore, conditional variable 等锁函数. 通过分析call trace 的代码,能直接确定各进程在执行到该位置时,可能已经持有的全部锁, 根据这个修改程序的代码,消除死锁环路,就可解决问题.

注意,内存故障也可导致假的死锁的,如物理内存故障可直接导致锁变量的值为-1, 所以使用该锁的进程都会阻塞. 如果是代码的bug导致的内存corruption,可用valgrind工具检查程序来发现. 但如果是物理内存的故障定位导致的corruption, 则需要硬件的支持,对于高端的PC, 如MCE功能的机器,当物理内存故障定位时能直接产生异常或报告, 但对于低端PC服务器,除了运行memtest工具进行检测外,没有其他方法

(4)进程长期处于 'D' (UnInterruptible)状态没法退出

这种多是由内核中的故障引起的. 内核在很多执行路径中会将进程至于'D'的状态,以确保关键的执行路径不被外部的信号中断, 导致不必要的内核中数据结构状态的不一致性. 但一般而言,进程处于 'D' 状态的时间不会太久, 因为状态结束的条件(如timer触发,

IO操作完成等)很快会将进程唤醒. 当进程长期处于 'D',关键是要找出其阻塞的代码位置, 用 sysrq 的t键功能可直接打印出系统中全部睡眠进程的内核执行堆栈,如 echo 't' > /proc/sysrq-trigger, 其中包括出现 'D'状态的进程的内核态堆栈. 找出代码位置后,一般可直接分析出 'D' 状态不能退出的原因, 如IO read操作因硬件或nfs故障而不能完成.

有可能导致 'D' 状态的原因比较复杂,如‘D’的退出依赖于某变量的值,而该变量的值因某种原因被永久corrupted掉了.

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

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

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

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

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

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

    红帽Linux故障定位技术详解与实例(2) 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. Python:Django 项目中可用的各种装备和辅助

    1 Redis 数据库 2 MySQL 数据库 3 前端服务器 live-server 4 定时任务 django-crontab扩展 5 Docker 容器 --用来运行 FastDFS 分布式文件 ...

  2. C#编程 线程,任务和同步(2) 开启线程

    创建线程的几种方法: 1 异步委托 创建线程的一种简单方式是定义一个委托,并异步调用它. 委托是方法的类型安全的引用.Delegate类 还支持异步地调用方法.在后台,Delegate类会创建一个执行 ...

  3. 03-MySQL多表操作

    一.表之间的关系 1.如何找出两张表之间的关系 分析步骤: #.先站在左表的角度去找 是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是 ...

  4. 论文阅读 | Combating Adversarial Misspellings with Robust Word Recognition

    对抗防御可以从语义消歧这个角度来做,不同的模型,后备模型什么的,我觉得是有道理的,和解决未登录词的方式是类似的,毕竟文本方面的对抗常常是修改为UNK来发生错误的.怎么使用backgroud model ...

  5. [转帖]Docker常用命令总结

    Docker常用命令总结 http://www.ha97.com/5546.html 发表于: Linux, 互联网, 虚拟化与云计算 | 作者: 博客教主 标签: docker,常用命令,总结 PS ...

  6. java中start()、yield、setDeamon()

    本节主要说明以下三个问题 start()的启动顺序不代表线程的启动顺序 yeild的作用 守护线程 1.start()与线程启动顺序 package foreverly.cn.chapter1; pu ...

  7. GitHub从小白到熟悉<四>

    GitHub issue 使用教程 创建 一个issue  (显示所有bug 或者 说 交流的 问题列表)

  8. python flask解决上传下载的问题

    记录瞬间 最近为了解决一些新的需求,简单介入了flask对文件的上传和下载的方法,并分别使用python和curl模拟发送 代码: #! /usr/bin/env python3 # coding:u ...

  9. FluentValidation在C# WPF中的应用

    原文:FluentValidation在C# WPF中的应用 一.简介 介绍FluentValidation的文章不少,零度编程的介绍我引用下:FluentValidation 是一个基于 .NET ...

  10. php运行结果设置无缓存

    修改配置php.ini vim /usr/local/php/lib/php.ini opcache.enable= 重启php服务 service php-fpm restart done! 参考地 ...