SYSTEM SERVER进程ANR 一般会导致java vm不停重启,还好保留了自动打印log到文件中的方法,出现这种概率性问题,从log入手就简单多了。
1. 找到SYSTEM server的PID,一般在logcat中会有这么一句
System server process 2094 has been created; 2094就是你需要的PID
2. 根据pid去搜索写入anr的地方,比如log中应该会有下面这些log:
05-10 11:10:02.360 I/Process ( 2094): Sending signal. PID:
2094 SIG: 3 这里发了SIGQUIT ----向system server进程发quit信号,这里是“果”
05-10 11:10:02.360 I/dalvikvm( 2094): threadid=4: reacting to signal 3
05-10 11:10:02.420 I/dalvikvm( 2094): Wrote stack traces to '/data/anr/traces.txt'
之后也一定会有类似的kill log:
05-10 11:10:34.860 I/Process ( 2094): Sending signal. PID:
2094 SIG: 9
05-10 11:10:34.860 W/Watchdog( 2094): *** WATCHDOG KILLING SYSTEM PROCESS: null ---- 这里发出了kill
至于ANR的“因”,继续在log中往上寻找,也一定能有类似的语句:
05-10 11:09:37.980 W/ActivityManager( 2094): Timeout of broadcast
BroadcastRecord{2b1a7f48 android.intent.action.SCREEN_OFF} --这里就是"因"SCREEN_OFFtimeout
05-10 11:09:37.980 W/ActivityManager( 2094): Receiverduring timeout: BroadcastFilter{2b161a08 ReceiverList{2b1619d0 2094 system/1000 local:2b130420}}
3. 根据上面的出现“因”的时间戳,去kernel中寻找相应的点,看是否有错。运气好的话在附近的logcat或kernellog中能找到具体的问题点。
笔者遇到的SCREEN_OFF 导致的VM重启是suspend时引起的,具体原因就不说了。
另外:一般的ANR可以从/data/anr/traces.txt (默认是开启的)中看到最后停在哪个函数上。