美文网首页
记录一次Kernel panic异常分析

记录一次Kernel panic异常分析

作者: Hemsl | 来源:发表于2019-06-26 18:13 被阅读0次

我司做的是Android工控机产品,最近合作客户的机器遇到一个问题,有台故障机运行过程中不定时重启,分析过程具体如下:

一. 机器重启,log丢失怎么办?

Android有/proc/last_kmsg的节点,可以看到上一次崩溃的原因。引用网友的一段解释:

来自:https://blog.csdn.net/dc3120/article/details/88573324

android要求平台提供一块固定的内存,作为ram_console的存储空间。然后通过“代码:register_console(&ram_console);”,将ram_console注册到printk输出的console_list中去,所以printk会时时向ram_console中输出kernel log。在ram_console头部有一个“代码:RAM_CONSOLE_SIG”的签名,每次android设备启动的时候,会check头部的签名是否正确。如果正确,那就会将ram_console中的内容保起来,生成一个/proc/last_kmsg的节点,用来查看上次最后的kernel log。如果不正确,就不会生成last_kmsg。

这样在修改芯片原厂的固件代码的时候,最好自己添加一个日志记录的功能,Android层logcat的日志信息、kernel中的日志信息,当前这次启动的logcat/kmsg、last logcat/kmsg的整理同步到机器的同一个目录中,方便出问题时排查。

因为有这个日志机制,那么直接让客户帮忙拉取日志,日志错误部分如下:

二.分析问题原因

可以很明显的看到Kernel painc的错误,但是具体怎么定位呢?只能使出必杀技了,addr2line,具体分为两个步骤:

1. 出错的pc指针指向的地址:PC is at end_buffer_async_read+0x14/0x1ec,直接找到end_buffer_async_read函数的地址+0x14就是出错的代码的行数,可以通过addr2linux定位。addr2line的命令是:

arm-linux-androideabi-addr2line  pc指定指向的地址 -e kernel/vmlinux -f

2. 反编译内核镜像vmlinux文件来找到这个地址,这里需要注意的是,正常发布的kernel编译的时候Makefile没有添加-g选项,出于安全考虑,导致不能获取到真实的代码的行数等信息。这时可以重新再次添加-g选项编译kernel,具体修改如下:

编译生成新的vmlinux后执行:

arm-linux-androideabi-objdump -Dz-S vmlinux > linux.dump

使用UltraEdit打开linux.dump,找到end_buffer_async_read的地址,然后在加上0x14就是出问题的真实的地址,这里算出来是0xc0132508 ;这时执行最后一步:

arm-linux-androideabi-addr2line 0xc0132508 -e kernel/vmlinux -f

返回的结果如下:

# end_buffer_async_read

# /home/path/kernel/fs/buffer.c:273

kernel/fs/buffer.c的273行就是错误所在,查看代码是:

BUG_ON(!buffer_async_read(bh)); 

分析上下文,最后就剩下推测分析问题出现的原因、并且给客户一个解释。

相关文章

网友评论

      本文标题:记录一次Kernel panic异常分析

      本文链接:https://www.haomeiwen.com/subject/acchcctx.html