欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[笔记分享] [Exception] 内核空间异常之流程小结

程序员文章站 2024-02-22 21:04:16
...

平台: MSM8260
OS: Android 2.3.4

Overview

本文主要描述下kernel exception(这里以oops为主线)的flow以及如何对oops进行分析作一个讲解。

Exception flow

1.1 介绍

android系统上的exception的大致流程:

[笔记分享] [Exception] 内核空间异常之流程小结

从arm_notify_die开始,左边是Kernel exception flow, 右边为user space exception flow,也就是说当exception处于user space时,kernel会发送信号给user space, 而不会像kernel exception一样会down机。

另外,我们发现,各种excetpion type和arm的exception基本上是对应的。如data abort, prefetch abort。

从图上看到,不管是哪种异常都会进入arm_notify_die,然后再die。其实经常碰到的exception不会经过arm_notify_die, 而是直接调用了do_page_fault就返回,不过没关系,do_page_fault最终也会调用die或者是force_sig_info。一会我们从代码中就可以看到了。

1.2Recieve

那么系统是如何知道一个exception发生的呢。拿kernel data abort为例(后面都是),当我们在kernel中对一个虚拟地址进行访问的时候,如0x12345678,但在系统初始化的时候,该地址所对应的权限是禁止访问,MMU捕捉到访问0x0的action之后,但是发现初始化时是设置禁止访问的,然后它就设置相关registers,产生一个exception。

[笔记分享] [Exception] 内核空间异常之流程小结

1.3 Handler

1.3.1 汇编部分

Ok, exception 产生了, 到了区分是哪种exception的时候。 每种体系结构的exception都不尽相同,
我们是arm平台,所以对应的文件为aaa@qq.com:\1090\android\kernel\arch\arm\kernel。

Exception时,首先进入异常向量表:

[笔记分享] [Exception] 内核空间异常之流程小结

这里暂不讨论vector table放在高端时是如何跳转,毕竟exception为theme嘛,有兴趣的童鞋可参考http://blog.csdn.net/hongtao_liu/article/details/4263176 。所以这里不讨论直接进入vector_dabt + stubs_offset所对应地址:

[笔记分享] [Exception] 内核空间异常之流程小结

虽然arm有好多种工作模式,但是在linux上只有两种,user和svc mode。这也使得linux在x86上的处理简单很多,题外话….

Vector_stub为一个宏:

[笔记分享] [Exception] 内核空间异常之流程小结

Asm相对c看起来比较吃力(自己不熟悉也是原因咯–!),熬一熬就出头了。大概的意思就是保存当前当前信息(lr, cpsr, r0), 准备进入SVC mode前一些工作(不管是user还是kernel exception时都会进入svc mode), 然后判断产生exception的Mode, 最后跳转到相应handler。

那么我们这里就是进入了__dabt_svc了:

[笔记分享] [Exception] 内核空间异常之流程小结

可以看到,不管是user还是kernel exception, 最终都会调用do_DataAbort, 只是kernel exception就reboot了。这里我们要关注的是r0保存了exception的address, r1保存了fault status。至于其他信息,如各种register, 是通过stack传参给do_DataAbort了。

顺便说下,arm中asm到c的传参是通过r0-r3, 当参数多个4个之后,就可以使用stack传递,当然你也可以都用stack传递,没人会说你违法的….

1.3.2 C语言部分

终于熬出头进入了c语言部分,稍稍有点激动,稳住,看aaa@qq.com:\1090\android\kernel\arch\arm\mm。你会发现里面有do_PrefetchAbort, do_ DataAbort。还有其他一些函数后面会提到。这里以do_ DataAbort举例:

[笔记分享] [Exception] 内核空间异常之流程小结

先看其参数,addr就是r0, fsr是r1, 而且pregs就是通过stack传过来的。先执行inf->fn, inf是什么 ?看const struct fsr_info *inf = fsr_info + fsr_fs(fsr);, 你会发现它发现根据fualt status value(fsr变量)去相应的inf,每个fsr_info都有自己的fn,然后通过inf->fn调用。

[笔记分享] [Exception] 内核空间异常之流程小结

很多fn都是do_bad,其实它只是个空函数,

[笔记分享] [Exception] 内核空间异常之流程小结

这样它就可以执行inf->fn后面的语句也就是arm_notify_die了。

不过从测试当中发现,不管是data abort还是prefect abort,执行的基本上是fsr_info中的do_page_fault函数,因为一般的错误基本上是引用控制值,或者访问了没有访问权限的地址之类。

因此,我们转去看do_page_fault。

[笔记分享] [Exception] 内核空间异常之流程小结

其实这个函数主要是处理缺页申请的。它是为虚拟内存管理所服务的。过程为这样子:当取的虚拟地址有效,但是其所对应的也不在当前物理内存,系统必须要从磁盘或者交换文件中装入内存。

对于缺页申请,这里就不描述了。当是use mode的exception时, __do_user_fault会call到force_sig_info发送信号给用户空间,让用户空间处理exception, 然后返回到之前说的汇编部分继续执行被exception打断前的事,当然并不一定是之前的process咯,因为return时会发生schedule嘛!

忘了一件重要事情:oops的log信息是怎么样的我们到现在还没看过呢!内容有点多,sorry,我也不想…

1>[   24.566404] Unable to handle kernel paging request at virtual address 1234
5678
<1>[   24.566432] pgd = dbe50000
<1>[   24.575600] [12345678] *pgd=00000000
<0>[   24.578896] Internal error: Oops: 805 [#1] PREEMPT SMP
<0>[   24.584132] last sysfs file: /sys/lcd/lcd_display
<4>[   24.588558] Modules linked in:
<4>[   24.591862] CPU: 1    Not tainted  (2.6.35.7+ #47)
<4>[   24.596647] PC is at lcd_display_show+0x20/0x40
<4>[   24.601064] LR is at kobj_attr_show+0x18/0x1c
<4>[   24.605228] pc : [<c02dad2c>]    lr : [<c0292754>]    psr: a0000013
<4>[   24.605234] sp : dbe43f10  ip : 00000002  fp : bedffd9a
<4>[   24.616771] r10: 00000fff  r9 : 00001000  r8 : c062598c
<4>[   24.622068] r7 : dbe43f80  r6 : df025c40  r5 : dfa199f0  r4 : dbe1b000
<4>[   24.628664] r3 : 12345000  r2 : 00000031  r1 : c072bbc6  r0 : dbe1b000
<4>[   24.635176] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment u
ser
<4>[   24.642033] Control: 10c57c7d  Table: 5c05006a  DAC: 00000015
<4>[   24.647761]
<4>[   24.647763] PC: 0xc02dacac:
<4>[   24.652187] acac  e3530031 1a000010 e59f0048 eb0c7969 e3a00000 e5c5400c eb
ff8b40 ea00000a
<4>[   24.660434] accc  e3540031 1a000008 e59f5024 e5d5300c e3530030 1a000004 e5
9f001c eb0c795d
<4>[   24.668594] acec  e3a00000 e5c5400c ebff8b55 e3a00000 e8bd8070 c0868fc8 c0
75ba4f c075ba6c
<4>[   24.676753] ad0c  e59f302c e1a00002 e92d4010 e1a04002 e5d3200c e3a0c002 e5
9f3018 e59f1018
<4>[   24.684913] ad2c  e583c678 ebfefbb1 e1a00004 e8bd4010 eafef2cf c0868fc8 12
345000 c072bbc6
<4>[   24.693072] ad4c  e59f3020 e1a00002 e92d4010 e59f1018 e1a04002 e5932000 eb
fefba4 e1a00004
<4>[   24.701231] ad6c  e8bd4010 eafef2c2 c094fb30 c07263ea e59f3020 e1a00002 e9
2d4010 e59f1018
<4>[   24.709392] ad8c  e1a04002 e5932004 ebfefb98 e1a00004 e8bd4010 eafef2b6 c0
94fb30 c07263ea
<4>[   24.717552]
<4>[   24.717555] LR: 0xc02926d4:
<4>[   24.721717] 26d4  e1a00006 e1a01005 e8bd47f0 eafffc50 e1a01007 e59f0004 e8
bd47f0 ea0d9adb
<4>[   24.729965] 26f4  c07516e5 e3a03101 ea000000 e1a03123 e1530000 8afffffc e1
a02000 e3a00000
<4>[   24.738124] 2714  ea000004 e1520001 20800083 20612002 e1a03123 e1a000a0 e3
530000 e0831000
<4>[   24.746284] 2734  1afffff7 e12fff1e e92d4010 e591300c e3530000 03e00004 08
bd8010 e12fff33
<4>[   24.754443] 2754  e8bd8010 e92d4010 e591c010 e35c0000 03e00004 08bd8010 e1
2fff3c e8bd8010
<4>[   24.762603] 2774  e2503000 e92d4010 0a000005 e5933014 e593300c e3530000 0a
000001 e12fff33
<4>[   24.770762] 2794  e8bd8010 e3a00000 e8bd8010 e590000c eafffff2 eafc18d2 e9
2d4010 e1a0200d
<4>[   24.778922] 27b4  e3c23d7f e3c3303f e5932004 e2822001 e5832004 e59f308c e3
a02001 e1931f9f
<4>[   24.787084]
<4>[   24.787086] SP: 0xdbe43e90:
<4>[   24.791250] 3e90  00000000 c01175cc 00000000 00000041 c0892c80 00000000 00
000000 1dfb443b
<4>[   24.799496] 3eb0  00000000 ffffffff dbe43efc df025c40 dbe43f80 c003fd2c db
e1b000 c072bbc6
<4>[   24.807656] 3ed0  00000031 12345000 dbe1b000 dfa199f0 df025c40 dbe43f80 c0
62598c 00001000
<4>[   24.815815] 3ef0  00000fff bedffd9a 00000002 dbe43f10 c0292754 c02dad2c a0
000013 ffffffff
<4>[   24.823974] 3f10  df025c58 c0292754 df025c58 c0196774 0003c000 0000003c db
e1e17c 00000002
<4>[   24.832134] 3f30  dbe1e180 0003c008 0003e000 00001000 df0b0780 0003c008 db
e43f80 00001000
<4>[   24.840295] 3f50  dbe42000 00000000 bedffd9a c0144e34 df0b0780 0003c008 df
0b0780 0003c008
<4>[   24.848454] 3f70  00000000 00000000 00001000 c0144f88 00000000 00000000 00
001000 00000000
<4>[   24.856614]
<4>[   24.856617] R0: 0xdbe1af80:
<4>[   24.860780] af80  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   24.869028] afa0  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   24.877186] afc0  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   24.885347] afe0  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   24.893507] b000  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   24.901666] b020  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   24.909826] b040  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   24.917986] b060  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   24.926146]
<4>[   24.926148] R1: 0xc072bb46:
<4>[   24.930312] bb44  676e6972 656f6420 74276e73 74696620 206e6920 63207525 73
726168 3c000a2e
<4>[   24.938558] bb64  73253e33 7865203a 74636570 72612073 656d7567 0a73746e 3e
333c00 203a7325
<4>[   24.946718] bb84  206e6163 796c6e6f 6b617420 69252065 67726120 6e656d75 00
0a7374 333c002c
<4>[   24.954878] bba4  3a73253e 65656e20 61207364 656c2074 20747361 61206925 6d
756772 73746e65
<4>[   24.963037] bbc4  6325000a 756c2500 696c2500 00692500 00756825 00696825 25
3e333c 73203a73
<4>[   24.971197] bbe4  6e697274 61702067 656d6172 20726574 65707865 64657463 33
3c000a 3a73253e
<4>[   24.979357] bc04  72747320 20676e69 61726170 6574656d 6f742072 6f6c206f 00
0a676e 703e343c
<4>[   24.987517] bc24  65737261 6772615f 3a292873 74706f20 206e6f69 27732527 61
6e6520 64656c62
<4>[   24.995677] bc44  71726920 0a217327 3e333c00 203a7325 6e6b6e55 206e776f 61
726170 6574656d
<4>[   25.003836]
<4>[   25.003839] R4: 0xdbe1af80:
<4>[   25.008003] af80  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   25.016249] afa0  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   25.024410] afc0  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   25.032568] afe0  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   25.040729] b000  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   25.048888] b020  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   25.057049] b040  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   25.065208] b060  00000000 00000000 00000000 00000000 00000000 00000000 00
000000 00000000
<4>[   25.073367]
<4>[   25.073370] R5: 0xdfa19970:
<4>[   25.077534] 9970  dfa00a00 00000000 dfa017c0 dfa19990 00000001 000041ed 00
000034 00000000
<4>[   25.085781] 9990  00000001 00000000 dfa19960 dfa199c0 c075ba88 00000000 c0
868fe8 00000000
<4>[   25.093941] 99b0  00000002 000081a4 00000035 00000000 00000001 00000000 df
a19960 dfa199f0
<4>[   25.102100] 99d0  c075ba96 00000000 c0868ffc 00000000 00000002 000081a4 00
000036 00000000
<4>[   25.110259] 99f0  00000003 00000001 dfa19960 00000000 c075baa3 00000000 c0
869010 de6f8180
<4>[   25.118419] 9a10  00000002 000081a4 00000037 00000000 00000081 00000000 df
a19120 dfa863c0
<4>[   25.126579] 9a30  dfa00a40 00000000 dfa02e4c dfa871e0 00000001 000041ed 00
000038 00000000
<4>[   25.134739] 9a50  00000003 00000000 dfa193c0 dfa19a80 dfa00aa0 00000000 df
a01800 00000000
<4>[   25.142899]
<4>[   25.142902] R6: 0xdf025bc0:
<4>[   25.147066] 5bc0  df454800 00000000 dfb3e5f0 df0472a0 ffff8e8a 0000000c 00
0000f5 00000000
<4>[   25.155312] 5be0  def1f760 df025b60 00000000 df0472c4 c028a954 c028a848 00
000000 00000000
<4>[   25.163472] 5c00  df025080 e033f000 00000006 df025c0d 00000000 dfd842cc df
44b3d8 00200200
<4>[   25.171631] 5c20  df025ae0 def1fea0 de6f8300 df025aec c0132180 00000000 00
000000 00000000
<4>[   25.179792] 5c40  00000000 00000000 00000000 00000000 dbe1b000 c062598c 00
000000 00000000
<4>[   25.187950] 5c60  df025c60 df025c60 dbe42000 00000001 00000001 de6f8194 de
6f8194 00000000
<4>[   25.196111] 5c80  00000000 00000001 00000000 00000000 00000000 00000000 df
025c98 df025c98
<4>[   25.204270] 5ca0  c0831e10 c0831e10 3a303065 64323861 34323634 00000000 00
000000 00000000
<4>[   25.212431]
<4>[   25.212434] R7: 0xdbe43f00:
<4>[   25.216597] 3f00  c0292754 c02dad2c a0000013 ffffffff df025c58 c0292754 df
025c58 c0196774
<4>[   25.224843] 3f20  0003c000 0000003c dbe1e17c 00000002 dbe1e180 0003c008 00
03e000 00001000
<4>[   25.233003] 3f40  df0b0780 0003c008 dbe43f80 00001000 dbe42000 00000000 be
dffd9a c0144e34
<4>[   25.241162] 3f60  df0b0780 0003c008 df0b0780 0003c008 00000000 00000000 00
001000 c0144f88
<4>[   25.249322] 3f80  00000000 00000000 00001000 00000000 0002f920 0002dcbc 00
02f920 00000003
<4>[   25.257481] 3fa0  c0040428 c0040280 0002f920 0002dcbc 00000003 0003c008 00
001000 0002f920
<4>[   25.265642] 3fc0  0002f920 0002dcbc 0002f920 00000003 0002f920 00000001 00
000003 bedffd9a
<4>[   25.273802] 3fe0  00000000 bedffb00 0000c33d 000081bc 60000010 00000003 68
809800 d0012804
<4>[   25.281962]
<4>[   25.281964] R8: 0xc062590c:
<4>[   25.286128] 590c  00000000 00000000 7465736b 6c65725f 65736165 00000000 61
6e7964 5f63696d
<4>[   25.294374] 592c  6a626f6b 6c65725f 65736165 00000000 6a626f6b 5f746365 61
656c63 0070756e
<4>[   25.302534] 594c  6a626f6b 5f746365 5f646461 65746e69 6c616e72 00000000 6a
626f6b 5f746365
<4>[   25.310694] 596c  61657263 615f6574 615f646e 00006464 6c6c6966 626f6b5f 61
705f6a 00006874
<4>[   25.318853] 598c  c029273c c0292758 c0751f10 c0751f14 c0751f1b c0751f22 c0
751f27 c0751f2e
<4>[   25.327013] 59ac  6a626f6b 5f746365 65766575 655f746e 0000766e 33323130 37
363534 42413938
<4>[   25.335174] 59cc  46454443 00000003 00000000 00000000 00000000 00000003 ff
ffffff 00000001
<4>[   25.343333] 59ec  00000001 00000001 ffffffff 00010203 06070405 0b0a0908 0f
0e0d0c 03020100
<0>[   25.351495] Process cat (pid: 243, stack limit = 0xdbe422f0)
<0>[   25.356963] Stack: (0xdbe43f10 to 0xdbe44000)
<0>[   25.361219] 3f00:                                     df025c58 c0292754 df
025c58 c0196774
<0>[   25.369380] 3f20: 0003c000 0000003c dbe1e17c 00000002 dbe1e180 0003c008 00
03e000 00001000
<0>[   25.377540] 3f40: df0b0780 0003c008 dbe43f80 00001000 dbe42000 00000000 be
dffd9a c0144e34
<0>[   25.385699] 3f60: df0b0780 0003c008 df0b0780 0003c008 00000000 00000000 00
001000 c0144f88
<0>[   25.393860] 3f80: 00000000 00000000 00001000 00000000 0002f920 0002dcbc 00
02f920 00000003
<0>[   25.402019] 3fa0: c0040428 c0040280 0002f920 0002dcbc 00000003 0003c008 00
001000 0002f920
<0>[   25.410178] 3fc0: 0002f920 0002dcbc 0002f920 00000003 0002f920 00000001 00
000003 bedffd9a
<0>[   25.418339] 3fe0: 00000000 bedffb00 0000c33d 000081bc 60000010 00000003 68
809800 d0012804
<4>[   25.426507] [<c02dad2c>] (lcd_display_show+0x20/0x40) from [<c0292754>] (k
obj_attr_show+0x18/0x1c)
<4>[   25.435705] [<c0292754>] (kobj_attr_show+0x18/0x1c) from [<c0196774>] (sys
fs_read_file+0xb8/0x1a8)
<4>[   25.444646] [<c0196774>] (sysfs_read_file+0xb8/0x1a8) from [<c0144e34>] (v
fs_read+0xa8/0x150)
<4>[   25.452889] [<c0144e34>] (vfs_read+0xa8/0x150) from [<c0144f88>] (sys_read
+0x3c/0x68)
<4>[   25.460705] [<c0144f88>] (sys_read+0x3c/0x68) from [<c0040280>] (ret_fast_
syscall+0x0/0x30)
<0>[   25.469208] Code: e5d3200c e3a0c002 e59f3018 e59f1018 (e583c678)
<4>[   25.478113] ---[ end trace 60d10fac127ddd04 ]---
<0>[   25.488152] Kernel panic - not syncing: Fatal exception

[笔记分享] [Exception] 内核空间异常之流程小结

mm参数为当前task的内存信息,其他参数不变。当addr比PAGE_SIZE小时,就被认为是NULL pointer, 例子是0x12345678.

#define PAGE_SHIFT      12
#define PAGE_SIZE       (_AC(1,UL) << PAGE_SHIFT)

然后打印mm相关信息,包括pgd, pte,不知我们平台上是否有使用pmd,有哪个大虾知道看本平台是几级页表请告知我一声。

[笔记分享] [Exception] 内核空间异常之流程小结

Mm打印的信息似乎对分析oops没什么用,可能是我水准还不够。接着就die了,名字取得真形象….
还记得图上执行arm_notify_die里有什么语句吗?对,也有个die,所以接着他们的操作都是一样的了~~~

[笔记分享] [Exception] 内核空间异常之流程小结
[笔记分享] [Exception] 内核空间异常之流程小结

printk(KERN_EMERG “Internal error: %s: %x [#%d]” S_PREEMPT S_SMP “\n”,str, err, ++die_counter) 指出当前kernel是否是可抢占,是否是多处理器, 以及exception的count数。

print_modules()指出当前关联的模块,如果没有那就不打咯~

__show_regs()显示当前register信息。

[笔记分享] [Exception] 内核空间异常之流程小结
[笔记分享] [Exception] 内核空间异常之流程小结

show_extra_register_data()会打印各种registers最近的256bytes的信息,其中一个SP在手动分析的时候就派上用场了。在解oops时我们再分析。

接着这里写图片描述

printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
        TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);

会从tsk中得的当前exception的名字,pid号以及stack的limit。这个limit不是size,而是它的栈顶address。

dump_mem()会将stack信息给打印出来,这里也有sp的一些信息供我们分析。

dump_backtrace()这里不跟了,代码较多,它主要是利用当前sp中的lr信息,然后从/proc/kallsyms里查找对应的函数,然后将function call stack个打印出来,看到了函数名,我们就容易懂多了….

可见__die()函数是核心部分,后面就是一些收尾了。像panic中会在等待5秒之后重启系统。

[笔记分享] [Exception] 内核空间异常之流程小结