KE概念
Android OS由3层组成,最底层是kernel,上面是native bin/lib,最上层是java层:
任何软件都有可能发生异常,比如野指针,跑飞、死锁等等。
异常发生在kernel层,我们就叫它为KE(kernel exception),同理,发生在native就是NE,java层就是JE。这篇文章仅关注底层的KE。
KE类别
kernel有2中崩溃类别,
oops (类似assert,有机会恢复)
- oops是美国人比较常有的口语。就是有点意外,吃惊,或突然的意思。内核行为表现为通知感兴趣模块,打印各种信息,如寄存器值,堆栈信息…
- 当出现oops时,我们就可以根据寄存器等信息调试并解决问题。
- /proc/sys/kernel/panic_on_oops为1时导致panic。我们默认设置为1,即oops会发生panic。
panic
- Panic – 困惑,恐慌,它表示Linux kernel遇到了一个不知道该怎么继续的情况。内核行为表现为通知感兴趣模块,死机或者重启。
- 在kernel代码里,有些代码加了错误检查,发现错误可能直接调用了panic(),并输出信息提供调试。
其实不管分类几种,都表示kernel出现故障,需要修复。那如何调试呢?就要看在发生异常时留了哪些信息帮我们定位问题了。
常用调试方法
凡是程序就有bug。bug总是出现在预料之外的地方。据说世界上第一个bug是继电器式计算机中飞进一只蛾子,倒霉的飞蛾夹在继电器之间导致了计算机故障。由于这个小虫子,程序中的错误就被称为了bug。
有Bug就需要Debug,而调试是一种很个性化的工作,十个人可能有十种调试方法。但从手段上来讲,大致可分为两类,在线调试 (Online Debug) 和离线调试 (Offline Debug).
- 在线调试, Online debug, 指的是在程序的运行过程中监视程序的行为,分析是否符合预期。通常会借助一些工具,如GDB和Trace32等。有时候也会借助一些硬件设备的协助,如仿真器/JTAG,但是准备环境非常困难,而且用起来也很麻烦,除非一些runtime问题需要外很少使用。
- 离线调试, Offline debug, 指的是在程序的运行中收集需要的信息,在Bug发生后根据收集到的信息来分析的一种手段。通常也分为两种方式,一种是Logging,一种是Memory Dump。
- Logging, 日志或者相关信息的收集,可以比较清晰的看到代码的执行过程,对于逻辑问题是一种有效的分析手段,由于其简单易操作,也是最为重要的一种分析手法。
- Memory Dump, 翻译过来叫做内存转储,指的是在异常发生的时刻将内存信息全部转储到外部存储器,即将异常现场信息备份下来以供事后分析。是针对CPU执行异常的一种非常有效的分析手段。在Windows平台,程序异常发生之后可以选择启动调试器来马上调试。在Linux平台,程序发生异常之后会转储core dump,而此coredump可以用调试器GDB来进行调试。而内核的异常也可以进行类似的转储。
下面我们由浅入深剖析各种调试方法,先从logging开始吧。