1. 程式人生 > >kernel空指標引起的system_server watchdog問題分析

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] [<ffffff94ce280adc>] 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 : [<ffffff94ce9ca228>] lr : [<ffffff94ce9a9ff0>] 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] [<ffffff94ce9ca228>] synaptics_rmi4_add_and_update_tp_data+0x24/0x124
<4>[ 0.884577] [<ffffff94ce9a9ff0>] input_event+0x20c/0x23c
<4>[ 0.884587] [<ffffff94ce9b750c>] synaptics_rmi4_sensor_report+0xa50/0x1008
<4>[ 0.884593] [<ffffff94ce9b9814>] synaptics_rmi4_irq+0x40/0x50
<4>[ 0.884604] [<ffffff94ce2f71b8>] irq_thread_fn+0x28/0x68
<4>[ 0.884610] [<ffffff94ce2f739c>] irq_thread+0xfc/0x1c4
<4>[ 0.884622] [<ffffff94ce2bba9c>] kthread+0xdc/0xe4
<4>[ 0.884631] [<ffffff94ce2845f0>] 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 : [<ffffff94ce2bc178>] lr : [<ffffff94ce2f74a8>] 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] [<ffffff94ce2bc178>] kthread_data+0x4/0xc
<4>[ 0.892980] [<ffffff94ce2ba250>] task_work_run+0x98/0xb8
<4>[ 0.892989] [<ffffff94ce2a4078>] do_exit+0x3e4/0x850
<4>[ 0.892998] [<ffffff94ce288650>] die+0x23c/0x254
<4>[ 0.893008] [<ffffff94ce2991a4>] __do_kernel_fault.part.5+0x74/0x90
<4>[ 0.893015] [<ffffff94ce2974d4>] do_page_fault+0x2ac/0x30c
<4>[ 0.893021] [<ffffff94ce297578>] do_translation_fault+0x44/0xc0
<4>[ 0.893028] [<ffffff94ce280adc>] 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] [<ffffff94ce283cfc>] el1_da+0x18/0x78
<4>[ 0.893114] [<ffffff94ce9a9ff0>] input_event+0x20c/0x23c
<4>[ 0.893122] [<ffffff94ce9b750c>] synaptics_rmi4_sensor_report+0xa50/0x1008
<4>[ 0.893129] [<ffffff94ce9b9814>] synaptics_rmi4_irq+0x40/0x50
<4>[ 0.893137] [<ffffff94ce2f71b8>] irq_thread_fn+0x28/0x68
<4>[ 0.893144] [<ffffff94ce2f739c>] irq_thread+0xfc/0x1c4
<4>[ 0.893151] [<ffffff94ce2bba9c>] kthread+0xdc/0xe4
<4>[ 0.893159] [<ffffff94ce2845f0>] 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程序還沒有起來