kernel空指针引起的system_server watchdog问题分析

一. 问题描述

1.1 现象

  手机kernel启动时狂点屏幕会导致手机卡死重启.

1.3 结论

  因为surfaceflinger主线程在等中断处理函数执行执行结束,而中断处理函数一直没有执行完,所以导致surfaceflinger的主线程卡住.这时候system_server通过binder跨进程去调用 surfaceflinger中的方法时,由于surfaceflinger卡住了,所以system_server也会被卡住,最终导致了system_server watchdog.

1.4修复链接:

  XXX


二. 初步分析

2.1 查看system_server trace


  一般对于watchdog问题,我们都会先看看system_server的那一个线程出了问题,出现问题的具体调用栈如下:

从这里我们能看到system_server的binder线程在向surfaceflinger发起跨进程调用时被block了,具体的调用方法是createSurface,那么接下来我们就去看看surfaceflinger的trace,看看它在干什么事情.

2.1 查看surfaceflinger trace

  我下了好几份log,都没有发现watchdog文件中有surfaceflinger的trace,没有能继续往下分析,只能先去找没有打印出surfaceflinger trace的原因.
2.2 surfaceflinger打不出trace的怀疑点
①debuggerd出问题了?
不会出问题,要是它出了问题,其他native进程也不会打印出对应的trace.
②watchdog类里把中surfaceflinger这个要抓trace的进程给去掉了?然后查看了下c8对应的代码:

surfaceflinger这个进程还在默认的列表里面,这就比较奇怪了,然后再继续下载了几十份Log,然而没有一份log有surfaceflinger的trace.
继续看下相应的Log,debuggerd确实打印了相应的log

12-29 20:42:17.814 695 831 W SurfaceFlinger: setTransactionState timed out waiting for previous animation frame
12-29 20:42:19.695 2912 3259 W PushService: 2017-12-29 20:42:19,695 - [WARN::PushService] - [Thread:99] [Slim] Wrote {cmd=SECMSG;chid=5;len=341}
12-29 20:42:19.695 2912 3259 W PushService: 2017-12-29 20:42:19,695 - [WARN::PushService] - [Thread:99] [Slim] 08:42:19 ä¸å Sent Blob [SECMSG,5,5QbAV-13]
12-29 20:42:19.695 933 5418 I ExtendedUtils: printFileName fd(15) -> /system/media/audio/notifications/CrystalRing.ogg
12-29 20:42:19.695 2912 3259 W PushService: 2017-12-29 20:42:19,695 - [WARN::PushService] - [Thread:99] try send mi push message. packagename:com.miui.powerkeeper action:Notification
12-29 20:42:19.696 2912 3259 W PushService: 2017-12-29 20:42:19,695 - [WARN::PushService] - [Thread:99] [Slim] Wrote {cmd=SECMSG;chid=5;len=349}
12-29 20:42:22.955 695 831 W SurfaceFlinger: setTransactionState timed out waiting for previous animation frame
12-29 20:43:16.835 591 591 W : debuggerd: handling request: pid=695 uid=1000 gid=1003 tid=695
12-29 20:43:26.849 591 591 W : debuggerd: resuming target 695
12-29 20:43:26.854 591 591 W : debuggerd: handling request: pid=923 uid=1041 gid=1005 tid=923
12-29 20:43:26.857 590 590 W : debuggerd: handling request: pid=923 uid=1041 gid=1005 tid=923
12-29 20:43:26.999 591 591 W : debuggerd: handling request: pid=924 uid=1047 gid=1005 tid=924
12-29 20:43:27.000 590 590 W : debuggerd: handling request: pid=924 uid=1047 gid=1005 tid=924
12-29 20:43:27.106 591 591 W : debuggerd: handling request: pid=925 uid=1019 gid=1019 tid=925
12-29 20:43:27.107 590 590 W : debuggerd: handling request: pid=925 uid=1019 gid=1019 tid=925
12-29 20:43:27.120 591 591 W : debuggerd: handling request: pid=926 uid=0 gid=0 tid=926
12-29 20:43:57.857 5557 5557 W : debuggerd: handling request: pid=695 uid=1000 gid=1003 tid=695
12-29 20:44:07.870 5557 5557 W : debuggerd: resuming target 695
12-29 20:44:07.876 5557 5557 W : debuggerd: handling request: pid=923 uid=1041 gid=1005 tid=923
12-29 20:44:07.878 590 590 W : debuggerd: handling request: pid=923 uid=1041 gid=1005 tid=923
12-29 20:44:07.931 5557 5557 W : debuggerd: handling request: pid=924 uid=1047 gid=1005 tid=924
12-29 20:44:07.932 590 590 W : debuggerd: handling request: pid=924 uid=1047 gid=1005 tid=924
12-29 20:44:08.044 5557 5557 W : debuggerd: handling request: pid=925 uid=1019 gid=1019 tid=925
12-29 20:44:08.045 590 590 W : debuggerd: handling request: pid=925 uid=1019 gid=1019 tid=925
12-29 20:44:08.056 5557 5557 W : debuggerd: handling request: pid=926 uid=0 gid=0 tid=926


③surfaceflinger进程中的莫个线程D状态了.
由于没有现场,无法确认.

由于第一,第二种都被排除了,只有第三种最可疑了,如果是第三种情况的话,那就肯定是bsp同事合入的代码有问题导致的.

2.3 排查当时合入的代码

  由于没有surfaceflinger的trace,暂时无法继续往下分析了.只能去排查当时进了哪些代码,并且让测试帮忙跑稳定性测试,看看能不能复现.然后排查了一波代码,发现几个改动比较大的,发了邮件让相关的owner自己检查一下,具体的change如下:

XXX


邮件也发完了,但是大家好像都比较自信,都相信自己的change没有问题.

2.4 重新查看Log,查找规律

  大家都不愿意怀疑自己的change有问题,只能重新回去看看log.看下所有的Log中共同存在的特征.然后终于找到了突破口:

<2>[ 0.883908] Kernel BUG at ffffff94ce9ca228 [verbose debug info unavailable]
<0>[ 0.883914] Internal error: Oops - BUG: 96000005 [#1] PREEMPT SMP
<2>[ 0.892330] Kernel BUG at ffffff94ce2bc178 [verbose debug info unavailable]
<0>[ 0.892335] Internal error: Oops - BUG: 96000005 [#2] PREEMPT SMP
<4>[ 0.893028] [] do_mem_abort+0x40/0x9c


第一个kernel空指针,具体详细log如下:

<1>[ 0.883781] Unable to handle kernel NULL pointer dereference at virtual address 00000200
<1>[ 0.883797] pgd = ffffff94d0e3f000
<1>[ 0.883802] [00000200] *pgd=00000001f65e2003, *pud=00000001f65e2003, *pmd=0000000000000000
<4>[ 0.883903] ------------[ cut here ]------------
<2>[ 0.883908] Kernel BUG at ffffff94ce9ca228 [verbose debug info unavailable]
<0>[ 0.883914] Internal error: Oops - BUG: 96000005 [#1] PREEMPT SMP
<4>[ 0.883921] Modules linked in:
<4>[ 0.883934] CPU: 0 PID: 327 Comm: irq/265-synapti Not tainted 4.4.21-perf-g91f9a92-00622-gee0535c #1
<4>[ 0.883939] Hardware name: Qualcomm Technologies, Inc. SDM 660 PM660 + PM660L, Int Codec, jason (DT)
<4>[ 0.883946] task: ffffffe1f38bbe80 ti: ffffffe1f37a4000 task.ti: ffffffe1f37a4000
<4>[ 0.883964] PC is at synaptics_rmi4_add_and_update_tp_data+0x24/0x124
<4>[ 0.883975] LR is at input_event+0x20c/0x23c
<4>[ 0.883980] pc : [] lr : [] pstate: 80000145
<4>[ 0.883985] sp : ffffffe1f37a7af0
......
<0>[ 0.884485] Process irq/265-synapti (pid: 327, stack limit = 0xffffffe1f37a4020)
<4>[ 0.884491] Call trace:
<4>[ 0.884499] Exception stack(0xffffffe1f37a7920 to 0xffffffe1f37a7a50)
<4>[ 0.884505] 7920: ffffffe1f30a9800 0000008000000000 ffffffe1f37a7af0 ffffff94ce9ca228
<4>[ 0.884511] 7940: ffffffe1f37a7c30 ffffff94cf9a348d ffffff94cf988f15 0000000000000000
<4>[ 0.884517] 7960: ffffffe09522d600 0000000000000000 ffffffe1f48cc54c 0000000000000002
<4>[ 0.884524] 7980: ffffffe1f37a79b0 ffffff94ce58676c 0000000000000000 ffffffe09522d800
<4>[ 0.884530] 79a0: ffffffe09522de80 ffffff94cf289758 ffffffe1f37a79f0 ffffff94ce9f567c
<4>[ 0.884536] 79c0: 0000000000000000 0000000000000002 0000000000000007 0000000000000000
<4>[ 0.884542] 79e0: ffffffe1f30aa000 0000000000000001 000000000000009e ffffffe1f6075098
<4>[ 0.884549] 7a00: ffffffe1f37a7c20 ffffffe1f37a4000 00000000000008c0 0000000034ac5486
<4>[ 0.884555] 7a20: 0000000000989680 00000000001b69db 00000000004629df 00000000273b6cc9
<4>[ 0.884561] 7a40: 000000005a858216 0000000019d08b13
<4>[ 0.884569] [synaptics_rmi4_add_and_update_tp_data+0x24/0x124
<4>[ 0.884577] [] input_event+0x20c/0x23c
<4>[ 0.884587] [] synaptics_rmi4_sensor_report+0xa50/0x1008
<4>[ 0.884593] [] synaptics_rmi4_irq+0x40/0x50
<4>[ 0.884604] [] irq_thread_fn+0x28/0x68
<4>[ 0.884610] [] irq_thread+0xfc/0x1c4
<4>[ 0.884622] [] kthread+0xdc/0xe4
<4>[ 0.884631] [] ret_from_fork+0x10/0x20
<0>[ 0.884639] Code: f944a680 f90057a0 d0011a60 f947a800 (f9410000) 
<4>[ 0.884677] ---[ end trace e92029382e65dac3 ]---


这个log大概就是说irq/265-synapti进程在kernel里发生了一个空指针,空指针的位置在synaptics_rmi4_add_and_update_tp_data方法中
第二个kernel空指针,具体详细log如下:

<1>[ 0.892273] Unable to handle kernel paging request at virtual address ffffffffffffffd8
<1>[ 0.892278] pgd = ffffff94d0e3f000
<1>[ 0.892283] [ffffffffffffffd8] *pgd=0000000000000000, *pud=0000000000000000
<4>[ 0.892324] ------------[ cut here ]------------
<2>[ 0.892330] Kernel BUG at ffffff94ce2bc178 [verbose debug info unavailable]
<0>[ 0.892335] Internal error: Oops - BUG: 96000005 [#2] PREEMPT SMP
<4>[ 0.892339] Modules linked in:
<4>[ 0.892349] CPU: 0 PID: 327 Comm: irq/265-synapti Tainted: G D 4.4.21-perf-g91f9a92-00622-gee0535c #1
<4>[ 0.892354] Hardware name: Qualcomm Technologies, Inc. SDM 660 PM660 + PM660L, Int Codec, jason (DT)
<4>[ 0.892359] task: ffffffe1f38bbe80 ti: ffffffe1f37a4000 task.ti: ffffffe1f37a4000
<4>[ 0.892366] PC is at kthread_data+0x4/0xc
<4>[ 0.892373] LR is at irq_thread_dtor+0x44/0xb8
<4>[ 0.892378] pc : [] lr : [] pstate: 60000145
<4>[ 0.892383] sp : ffffffe1f37a7720
......
<0>[ 0.892886] Process irq/265-synapti (pid: 327, stack limit = 0xffffffe1f37a4020)
<4>[ 0.892890] Call trace:
<4>[ 0.892896] Exception stack(0xffffffe1f37a7550 to 0xffffffe1f37a7680)
<4>[ 0.892901] 7540: ffffffe1f38bbe80 0000008000000000
<4>[ 0.892908] 7560: ffffffe1f37a7720 ffffff94ce2bc178 ffffffbe47d25480 000000000001d518
<4>[ 0.892915] 7580: ffffffe1f37a4000 ffffff94ce2e1c80 ffffffe1f37a76b0 ffffff94ce3a46e0
<4>[ 0.892923] 75a0: ffffffbe47d25480 ffffffe1f4952a80 ffffffe1f37a4000 ffffffe1f6403e00
<4>[ 0.892931] 75c0: ffffffe1f37a4000 000000000001d518 ffffff94d08c9000 00000000000000ff
<4>[ 0.892937] 75e0: 0000000000000005 ffffffe1f37a4000 0000000000000000 ffffff94ce2f7464
<4>[ 0.892944] 7600: 0000000000000000 0000000000000000 ffffffe1f38bc598 0000000003acb1da
<4>[ 0.892950] 7620: 0000000000000004 0000000000000000 ffffffe1f4952aa0 ffffffe1f7562c88
<4>[ 0.892958] 7640: ffffffe1f7562c78 00000000352e65d8 0000000000989680 000000000019b13d
<4>[ 0.892965] 7660: 7265626d756e202c ffffff94cf2c0000 0000000000000007 000000000000000e
<4>[ 0.892972] [] kthread_data+0x4/0xc
<4>[ 0.892980] [] task_work_run+0x98/0xb8
<4>[ 0.892989] [] do_exit+0x3e4/0x850
<4>[ 0.892998] [] die+0x23c/0x254
<4>[ 0.893008] [] __do_kernel_fault.part.5+0x74/0x90
<4>[ 0.893015] [] do_page_fault+0x2ac/0x30c
<4>[ 0.893021] [] do_translation_fault+0x44/0xc0
<4>[ 0.893028] [] do_mem_abort+0x40/0x9c
<4>[ 0.893033] Exception stack(0xffffffe1f37a7920 to 0xffffffe1f37a7a50)
<4>[ 0.893039] 7920: ffffffe1f30a9800 0000008000000000 ffffffe1f37a7af0 ffffff94ce9ca228
<4>[ 0.893047] 7940: ffffffe1f37a7c30 ffffff94cf9a348d ffffff94cf988f15 0000000000000000
<4>[ 0.893052] 7960: ffffffe09522d600 0000000000000000 ffffffe1f48cc54c 0000000000000002
<4>[ 0.893059] 7980: ffffffe1f37a79b0 ffffff94ce58676c 0000000000000000 ffffffe09522d800
<4>[ 0.893066] 79a0: ffffffe09522de80 ffffff94cf289758 ffffffe1f37a79f0 ffffff94ce9f567c
<4>[ 0.893073] 79c0: 0000000000000000 0000000000000002 0000000000000007 0000000000000000
<4>[ 0.893079] 79e0: ffffffe1f30aa000 0000000000000001 000000000000009e ffffffe1f6075098
<4>[ 0.893086] 7a00: ffffffe1f37a7c20 ffffffe1f37a4000 00000000000008c0 0000000034ac5486
<4>[ 0.893094] 7a20: 0000000000989680 00000000001b69db 00000000004629df 00000000273b6cc9
<4>[ 0.893099] 7a40: 000000005a858216 0000000019d08b13
<4>[ 0.893107] [] el1_da+0x18/0x78
<4>[ 0.893114] [] input_event+0x20c/0x23c
<4>[ 0.893122] [] synaptics_rmi4_sensor_report+0xa50/0x1008
<4>[ 0.893129] [] synaptics_rmi4_irq+0x40/0x50
<4>[ 0.893137] [] irq_thread_fn+0x28/0x68
<4>[ 0.893144] [] irq_thread+0xfc/0x1c4
<4>[ 0.893151] [] kthread+0xdc/0xe4
<4>[ 0.893159] [] ret_from_fork+0x10/0x20
<0>[ 0.893166] Code: a9425bf5 a8c97bfd d65f03c0 f942dc00 (f85d8000) 
<4>[ 0.893172] ---[ end trace e92029382e65dac4 ]---
<1>[ 0.901675] Fixing recursive fault but reboot is needed!


这个log和第一个很类似就是irq/265-synapti进程在kernel里发生了一个空指针,空指针的位置在kthread_data方法中.
还有一个比较关键的一个地方是:
  Fixing recursive fault but reboot is needed!
这里说我们遇到了一个递归的故障,需要reboot才能解决,具体代码如下:

从我们的Log中也能看到这是一个连续发生的空指针问题,先发生了一次空指针,然后调用do_exit,在后续的流程中又发生了空指针,然后就陷入了一个循环挂掉的流程中,然后就调用到了schedule()方法,最终陷入D状态.

三. 深入分析

  初步分析后我们发现每次发生这个watchdog问题都有一个kernel 空指针问题发生,然后顺着这个空指针我们能找到当时合入的一个change:XXX
空指针的地方就是这个change里加入的,然后和钟桂林沟通了一下,有了这个复现路径。

因为我们抓到的所有trace文件中并没有surafaceflinger的trace,这个很有可能是由于surafaceflinger进程中的某个线程D状态了导致的.所以复现之后直接ps -t | grep " D "查看一下存在的D状态的线程,我们可以看到如下线程:

root 327 2 0 0 do_exit 0000000000 D irq/265-synapti
system 692 1 192972 40920 synchroniz 7fb6732320 D /system/bin/surfaceflinger


surfaceflinger和irq/265-synapti进程都D状态了

3.1 分析irq/265-synapti进程

  抓了一个kernel的ramdump,打印了一下当前的调用栈:


从这个调用栈中我们能看出有个中断处理函数在synaptics_rmi4_add_and_update_tp_data方法中发生了一次空指针,然后线程要退出,但是在执行到task_work_run方法中时又发生了空指针,然后调用到schedule方法.最终导致了这个线程D状态.(当手指触摸屏幕的时候会在硬件上产生一个中断,然后调用在probe函数中配置好的中断处理函数)
第一个空指针的具体推到如下:


我们从调用栈中能看到空指针的位置是在synaptics_rmi4_add_and_update_tp_data+36,然后我们可以看一下这个方法当时的汇编信息:
我们直接找到+36的位置:


我们从+28/+32/+36这几行大概能看出来如下内容:+28这行先将0xffffff8a9f318000地址的内容放到x0寄存器中,+32这行将x0寄存器偏移到相对x0的#3920,+36这行又将x0再偏移到相对x0的#512位置。
我们大概能知道这里是再取地址,然后再对比下源码:

结合汇编代码我们对再比代码后就能看出来,这里是在8208行出现问题了,出现问题的原因是:f54->rmi4_data是空指针。
f54是个全局变量对应:adrp x0, 0xffffff8a9f318000
然后我们要去取f54->rmi4_data的地址,对应:ldr x0, [x0,#3920]
接着我们去取f54->rmi4_data->es_enabled,对应:ldr x0, [x0,#512]
但是f54->rmi4_data是个空指针,所以在“ldr x0, [x0,#512]”时就会报错了,接着这个中断处理函数就挂了,接着就开始退出了。
第二个空指针的具体推到如下:
我们前边说了中断处理函数出现空指针然后开始退出,但是退出的时候又空指针了,我们直接去看的汇编信息:

直接对比下源代码:

这里也是在取地址的时候空指针的,这个空指针的具体原因就不深究了,很可能就是因为上一个task执行出错导致了,这里出现空指针,有兴趣的同学可以研究一下。
那么程序退出为什么会进入D状态呢?我们取看开exit.c中的代码:

就是线程在退出的时候陷入了一个循环,就会调用到schedule,最终该线程会进入到D状态

3.2 分析surfaceflinger进程

  好了irq/265-synapti进程中的主线程D状态的大概原因说完了,我们再看看surfaceflinger进程当时再干嘛:

jason:/ # ps -t 692
USER PID PPID VSIZE RSS WCHAN PC NAME
system 692 1 192972 40920 synchroniz 7fb6732320 D /system/bin/surfaceflinger
system 757 692 192972 40920 binder_thr 7fb6732320 S Binder:692_1
system 759 692 192972 40920 futex_wait 7fb66d5ef0 S DispSync
system 760 692 192972 40920 binder_thr 7fb6732320 S Binder:692_2
system 838 692 192972 40920 do_sigtime 7fb6732410 S POSIX timer 0
system 839 692 192972 40920 futex_wait 7fb66d5ef0 S EventThread
system 840 692 192972 40920 poll_sched 7fb6732350 S HWC_UeventThrea
system 846 692 192972 40920 poll_sched 7fb6732350 S SDM_EventThread
system 848 692 192972 40920 futex_wait 7fb66d5ef0 S EventControl
system 868 692 192972 40920 futex_wait 7fb66d5ef0 S Binder:692_3
system 2472 692 192972 40920 binder_thr 7fb6732320 S Binder:692_4
system 3558 692 192972 40920 binder_thr 7fb6732320 S Binder:692_5


我们发现surfaceflinger的主线程D状态了,然后我们接着看下692这个进程的kernel的调用栈:

我们这里直接找到对应的源码:

看到这里可能会有人有疑问了,调用栈里synchronize_irq里不是调用了schedule方法吗?这里没有看到这个方法呀,弄错了?开始我也怀疑我找错了,然后我们看下wati_event的定义,
我们能看到这里用的都是define来定义的,所以wat_event并不是一个具体的函数方法:

在__wait_event中我们传入了一个schedule方法,

最后会执行schedule方法。

我们再仔细看看synchronize_irq方法的注释:
/** * synchronize_irq - wait for pending IRQ handlers (on other CPUs)

* @irq: interrupt number to wait for  This function waits for any pending IRQ handlers for this interrupt

* to complete before returning. If you use this function while holding a resource the IRQ handler may need you will deadlock.

* This function may be called - with care - from IRQ context. */
大概意思是说:
synchronize_irq 方法在返回前需要等待任意一个 IRQ处理函程序数执行完成。当你持有中断处理程序时,如果你使用这个函数,就可能造成死锁。
那我们看看这里再等待哪一个irq呢?我们看到disable_irq方法中来,disable_irq方法的参数就是对应的irq,那么我们就从ramdump中来看开这个irq的值是多少,首先我们能看到如下方法:

disable_irq的第一个参数就是irq,那么我们就去找找这个参数的值是多少:

我们先看看这个方法的汇编信息,因为这个方法只有一个参数,他的irq就是存在w0寄存器中的,这个方法中我们并不能找到w0的地址我们继续往上一级函数synaptics_rmi4_irq_enable看看:

我们从disable_irq和synaptics_rmi4_irq_enable汇编信息来做如下推断:
1.disable_irq的irq保存再w0寄存器中,所以synaptics_rmi4_irq_enable方法在调用disable_irq方法时会将irq的值保存在w0中然后调用disable_irq方法,我们能看到disable_irq方法的地址是0xffffff8a9c8f7990,所以在synaptics_rmi4_irq_enable的栈中我们能找到这个地址,就是图上白色的地方,我们能看到w0是,x0偏移了#808得到的,我们再结合代码:

所以我们能推断出x0存的肯定是rmi4_data的地址。因为后边还会用到rmi4_data,而x0这个寄存器会在调用方法时被修改(传参),所以rmi4_data肯定会存在其他的寄存器上保存,我们在找找synaptics_rmi4_irq_enable栈上的信息,看看x0会把地址保存在哪一个寄存器上,我们能发现,他保存在了x19上,并且这个栈中没有再修改x19,那么我们再看到disable_irq栈上来:

x19是sp偏移16得到的,那么我们继续找到sp的地址:

所以x19的地址是:0xffffffce2f173a50+16
那么我们打印一下rmi4_data存的所有数据的值,里边肯定存在irq的值:

。。。

。。。
我们能找到对应的irq号,它为256.
当然了irq/265-synapti进程的调用栈也用类似的方法我们也能找到它的中断号,也为:265。这里就不反复推到浪费大家时间了。


三. 拨开云雾见青天

  我们再来回顾一下,首先是irq/265-synapti进程执行中断处理函数时发生了空指针异常自己连续挂了两次,并进入D状态卡住,然后surfaceflinger在等待它的中断处理函数执行结束,由于执行中断处理函数的进程已经进入D状态,因此中断处理函数永远无法执行结束,最终导致surfaceflinger也卡住了,这时候system_server通过同步binder 调用到surfaceflinger,因为surfaceflinger无法处理,所以system_server也会卡住,最终导致了system_server watchdog.所以这个问题只需要将最开始的空指针问题修复,那么就能修复这个问题了:XXX

四. 其他疑问

1.kernel空指针为什么没有重启?

没有重启的原因是没有走panic的流程,原因如下:

http://guard.pt.miui.com/opengrok2/xref/v8-n-jason-dev/kernel/msm-4.4/arch/arm64/kernel/traps.c#313
http://guard.pt.miui.com/opengrok2/xref/v8-n-jason-dev/kernel/msm-4.4/kernel/panic.c#34
触发panic有一个标志:panic_on_oops,它的值在c8上默认是0

311     if (in_interrupt())
312          panic("Fatal exception in interrupt");
313        if (panic_on_oops)
314              panic("Fatal exception");
315     if (notify != NOTIFY_STOP)
316               do_exit(SIGSEGV);
317}

panic_on_oops标志设置为1是在init进程中:
http://guard.pt.miui.com/opengrok2/xref/v8-n-jason-dev/system/core/rootdir/init.rc#114
发生这个空指针的时候init进程还没有起来


你可能感兴趣的:(安卓系统,kernel)