红帽 Linux 上的故障定位技术
1. 故障定位(Debugging)场景分类
为便于描述问题,将Linux 上各种软件故障定位的情形分成两类
A) 在线故障故障定位
在线故障定位(online-debugging)就是在故障发生时, 故障所处的操作系统环境
仍然可以访问,故障处理人员可通过 console, ssh 等方式登录到操作系统上,
在 shell 上执行各种操作命令或测试程序的方式对故障环境进行观察,分析,测
试,以定位出故障发生的原因
B) 离线故障定位
离线故障定位(offline-debugging)就是在故障发生时,故障所处的操作系统环
境已经无法正常访问,但故障发生时系统的全部或部分状态已经被系统本身所固
有或事先设定的方式收集起来,故障处理人员可通过对收集到的故障状态信息进
行分析,定位出故障发生的原因
2. 应用进程故障情形及处理
应用进程的故障一般不会影响操作系统运行环境的正常使用(如果应用代码的 bug
导致了内核的crash 或hang,则属于内核存在漏洞) ,所以可采用在线故障定位的方
法,灵活的进行分析. 应用代码故障的情形有如下几种:
A) 进程异常终止
很多用户认为进程异常终止情况无从分析,但实际上进程异常终止情况都是有迹
可寻的. 所有的进程异常终止行为,都是通过内核发信号给特定进程或进程组实
现的. 可分成几个类型进行描 :
● 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(), 也 有做