热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

androidkernelgps,android内核出现kernelpanic的分析

1何谓OOPSOops是美国人比较常有的口语。就是有点意外,吃惊,或突然的意思。“Oops”并不是很严重,正如在BritneySpears

1 何谓OOPS

Oops是美国人比较常有的口语。就是有点意外,吃惊,或突然的意思。“Oops”并不是很严重,正如在Britney Spears的 “Oops I Did It Again”那首歌的歌词中,也是一种轻描淡写,有时含有抱歉的意思。

对于Linux内核来说,Oops就意外着内核出了异常,此时会将产生异常时CPU的状态,出错的指令地址、数据地址及其他寄存器,函数调用的顺序甚至是栈里面的内容都打印出来,然后根据异常的严重程度来决定下一步的操作:杀死导致异常的进程或者挂起。

最典型的异常是在内核态引用了一个非法地址,通常是未初始化的野指针Null,这将导致页表异常,最终引发Oops。

系统足够健壮,能够正常的反应各种异常。异常通常导致当前进程的死亡,而系统依然能够继续运转,但是这种运转都处在一种不稳定的状态,随时可能出问题。对于中断上下文的异常及系统关键资源的破坏,通常会导致内核挂起,不再响应任何事件。

2 内核的异常级别

2.1 Bug

Bug是指那些不符合内核的正常设计,但内核能够检测出来并且对系统运行不会产生影响的问题,比如在原子上下文中休眠。如:

BUG: scheduling while atomic: insmod/826/0x00000002

Call Trace:

[ef12f700] [c00081e0] show_stack+0x3c/0x194 (unreliable)

[ef12f730] [c0019b2c] __schedule_bug+0x64/0x78

[ef12f750] [c0350f50] schedule+0x324/0x34c

[ef12f7a0] [c03515c0] schedule_timeout+0x68/0xe4

[ef12f7e0] [c027938c] fsl_elbc_run_command+0x138/0x1c0

[ef12f820] [c0275820] nand_do_read_ops+0x130/0x3dc

[ef12f880] [c0275ebc] nand_read+0xac/0xe0

[ef12f8b0] [c0262d98] part_read+0x5c/0xe4

[ef12f8c0] [c017bcac] jffs2_flash_read+0x68/0x254

[ef12f8f0] [c0170550] jffs2_read_dnode+0x60/0x304

[ef12f940] [c017088c] jffs2_read_inode_range+0x98/0x180

[ef12f970] [c016e610] jffs2_do_readpage_nolock+0x94/0x1ac

[ef12f990] [c016ee04] jffs2_write_begin+0x2b0/0x330

[ef12fa10] [c005144c] generic_file_buffered_write+0x11c/0x8d0

[ef12fab0] [c0051e48] __generic_file_aio_write_nolock+0x248/0x500

[ef12fb20] [c0052168] generic_file_aio_write+0x68/0x10c

[ef12fb50] [c007ca80] do_sync_write+0xc4/0x138

[ef12fc10] [f107c0dc] oops_log+0xdc/0x1e8 [oopslog]

[ef12fe70] [f3087058] oops_log_init+0x58/0xa0 [oopslog]

[ef12fe80] [c00477bc] sys_init_module+0x130/0x17dc

[ef12ff40] [c00104b0] ret_from_syscall+0x0/0x38

--- Exception: c01 at 0xff29658

LR = 0x10031300

2.2 Oops

程序在内核态时,进入一种异常情况,比如引用非法指针导致的数据异常,数组越界导致的取指异常,此时异常处理机制能够捕获此异常,并将系统关键信息打印到串口上,正常情况下Oops消息会被记录到系统日志中去。

Oops发生时,进程处在内核态,很可能正在访问系统关键资源,并且获取了一些锁,当进程由于Oops异常退出时,无法释放已经获取的资源,导致其他需要获取此资源的进程挂起,对系统的正常运行造成影响。通常这种情况,系统处在不稳定的状态,很可能崩溃。

2.3 Panic

当Oops发生在中断上下文中或者在进程0和1中,系统将彻底挂起,因为中断服务程序异常后,将无法恢复,这种情况即称为内核panic。另外当系统设置了panic标志时,无论Oops发生在中断上下文还是进程上下文,都将导致内核Panic。由于在中断复位程序中panic后,系统将不再进行调度,Syslogd将不会再运行,因此这种情况下,Oops的消息仅仅打印到串口上,不会被记录在系统日志中。

Kernelpanic调试举例:

[ 242.788019] bluesleep_outgoing_data: tx was sleeping

[  244.012224] ******host_wake is 1

[  245.234647] Disable_key_during_touch=0

[  245.237802] huqiao___button->code=139,state =1

[  245.414640] Disable_key_during_touch=0

[  245.417542] huqiao___button->code=139,state =0

[  245.821424] ******host_wake is 0

[  245.823708] bluesleep_hostwake_isr: [I]waking up...

[  245.823713]

[  245.830155] bluesleep_hostwake_task: bluesleep_hostwake_task is called

[  245.838356] Unable to handle kernel NULL pointer dereference at virtualaddress 00000008

[  245.845678] pgd = c0004000

[  245.848188] [00000008] *pgd=00000000

[  245.851751] Internal error: Oops: 5 [#1] PREEMPT SMP ARM

[  245.857122] Modules linked in:

[  245.860080] CPU: 0    Tainted: G        W    (3.4.0-perf-svn874 #1)

[  245.866444] PC is at sco_connect_cfm+0x380/0x4e8

[  245.871106] LR is at 0xd880

[  245.873800] pc : []    lr :[<0000d880>]    psr: 40000013

[  245.873805] sp : dbe55e78  ip : 00000000  fp : d7d95c00

[  245.885246] r10: d8643998  r9 : d8e5b80d  r8 : d8643830

[  245.890529] r7 : dbe54000  r6 : d9e5b600  r5 : cae27c80 r4 : d8643800

[  245.896968] r3 : 00000008  r2 : 00000000  r1 : d7d96016 r0 : 00000000

[  245.903552] Flags: nZcv  IRQs on  FIQs on  Mode SVC_32 ISA ARM  Segment kernel

[  245.910772] Control: 10c5787d  Table: 5a47406a  DAC: 00000015

[  245.916576]

[  245.916579] PC: 0xc0744640:

[  245.920751] 4640  e3310000 1afffffa f57ff04f e320f004 e5973004e2433001 e5873004 e5973000

[  245.928910] 4660  ea000042 e59f0190 e300332a e19030b3 e31300040a000004 e2800fc6 e59f1198

如上图&#xff0c;当出现kernel panic的时候&#xff0c;会出现上面所示的堆栈信息。我们可以看到 [  245.866444] PC is atsco_connect_cfm&#43;0x380/0x4e8&#xff0c;就会知道在sco_connect_cfm函数这边出现问题的。一般来说从LR(链接寄存器)这&#xff0c;我们可以知道上面的哪个函数是被hci_proto_connect_cfm所调用的。当看到Unable to handle kernel NULL pointerdereference at virtual address 00000008时&#xff0c;就知道这个函数应用了一个非法地址&#xff0c;在linux中&#xff0c; 将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF)&#xff0c;供内核使用&#xff0c;称为“内核空间”。而将较低的3G字节(从虚拟地址 0x00000000到0xBFFFFFFF)&#xff0c;供各个进程使用&#xff0c;称为“用户空间)&#xff0c;现在内核非法使用了用户空间的地址故存在问题。

关于kernel panic一般很难复现&#xff0c;于是我计划在内核中自己用代码去模拟这个现象。

static inlinevoid hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)

{

register struct hci_proto *hp;

hp &#61; hci_proto[HCI_PROTO_L2CAP];

if (hp && hp->connect_cfm)

hp->connect_cfm(conn, status);

hp &#61; hci_proto[HCI_PROTO_SCO];

if (hp && hp->connect_cfm)

hp->connect_cfm(conn, status);

if (conn->connect_cfm_cb)

conn->connect_cfm_cb(conn, status);

}

当我把函数改变为

static inlinevoid hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)

{

register struct hci_proto *hp;

hp &#61; hci_proto[HCI_PROTO_L2CAP];

if (hp && hp->connect_cfm)

hp->connect_cfm(conn, status);

conn &#61;  &#61; NULL - 21; // Simulation this phenomenon,

hp &#61; hci_proto[HCI_PROTO_SCO];

if (hp && hp->connect_cfm)

hp->connect_cfm(conn, status);

if (conn->connect_cfm_cb)

conn->connect_cfm_cb(conn, status);

}

这个现象就会完全的复现。

其实根据 hci_conn 结构体定义&#xff0c;我们就会知道 hcon->type的地址为00000008&#xff0c;于是我们就会明白&#xff0c;在最初的代码中&#xff0c;在调用sco_connect_cfm的时候&#xff0c;传入的变量conn的地址被改变为NULL - 21;但是在前面跑hp->connect_cfm(conn, status)却没有什么问题&#xff0c; conn的地址传进 hp->connect_cfm(conn, status)&#xff0c;也没有什么改变。于是我就开始郁闷了。为什么突然地址变为一个非法的地址&#xff1f;

后来在网上查了下&#xff0c;才发现可能是硬件的问题&#xff0c;使得某一个地址发生了临时的错误而导致的。于是找到了原因&#xff0c;这个bug也就分析结束了。



推荐阅读
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • Linux磁盘的分区、格式化的观察和操作步骤
    本文介绍了如何观察Linux磁盘的分区状态,使用lsblk命令列出系统上的所有磁盘列表,并解释了列表中各个字段的含义。同时,还介绍了使用parted命令列出磁盘的分区表类型和分区信息的方法。在进行磁盘分区操作时,根据分区表类型选择使用fdisk或gdisk命令,并提供了具体的分区步骤。通过本文,读者可以了解到Linux磁盘分区和格式化的基本知识和操作步骤。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • Ubuntu 9.04中安装谷歌Chromium浏览器及使用体验[图文]
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
author-avatar
虛情徦噫d_951
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有