1,可能导致kernel panic的原因有:
ARM捕捉到的异常 (KE)
指令异常:程序跑飞,可能跑到数据区里执行
访问无效地址:执行存取指令时抛出异常(访问了kernel space没有映射的内存)
代码主动发出的异常 (KE)
调用BUG()/BUG_ON()函数
软件卡死导致看门狗复位 (无法调度) (HWT)
代码出现死锁
中断被关太久(中断频繁)
硬件卡死导致看门狗复位 (HW_REBOOT)
CPU硬件卡死(bus hang)
虚焊/断路/短路等PCB问题
器件不良
2,内核的assert()函数
assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。果assert()返回失败,系统会强制因为assertion failed而panic,并将内存映象存入crash dump文件。
3,Crash工具学习
crash主页
内核部分的KEXEC+KDUMP的配置请参考:http://www.ibm.com/developerworks/cn/linux/l-cn-dumpanalyse/
# cp /proc/vmcore mydumpfile
正常linux内核发生异常的时候系统重启,那么重启之后系统内存里的异常信息就全部丢失了,而Crash机制的kdump就是将系统重启之前的内存信息dump出来并存储到相应的文件,这样后面可以通过Crash工具对这个内存进行分析系统异常的原因。比如可以打印backtrace等等。
4,oops机制
linux某个进程发生异常的时候发产生oops,oops 显示发生错误时处理器的状态,包括 CPU 寄存器的内容、页描述符表的位置,以及其一些难理解的信息,较为重要的信息就是指令指针(下一条指令的地址,EIP)由于很难从十六进制数值中看出含义,可使用符号解析工具klogd。klogd 守护进程能在 oops 消息到达记录文件之前对它们解码。通常Oops文本由klogd从内核缓冲区里读取并传给syslogd,由syslogd写到syslog文件中,该文件典型为/var/log/messages(依赖于/etc/syslog.conf)。如果klogd崩溃了,用户可"dmesg > file"从内核缓冲区中读取数据并保存下来。还可用"cat /proc/kmsg > file"读取数据,此时,需要用户中止传输,因为kmsg是一个"永不结束的文件"。
5,从kernel log查看当前发生异常时候pc指针的地址,然后用addr2line工具分析出此错误对应的源码位置
addr2line -e vmlinux 0xco2efe64
或者使用 b $(ADDRESS) in (gdb)分析
6,ram console。
ram console
答:是通过ram console,这个是放在internal ram的里,手机重启数据不会丢失,native层通过proc文件系统的
/proc/kmsg来读取重启之前最后的信息。
7,kernel处理kernel panic的流程
当arm发生异常的时候,那么最终会调用到arm_notify_die()函数,最终会调用到arch/arm/kernel/traps.c文件中的die()函数。