您的位置:首页 > 其它

watchdog杀死system_server导致系统重启问题分析流程

2017-07-20 15:56 696 查看
下面是最近在解一个monkey测试过程中系统重启的bug的分析过程,从这里我们可以看一下对于watchdog杀死死锁进程的一般分析流程。(这里当是一个笔记,没有详细按着文章的逻辑来整理词汇和语句 汗汗汗)

1. watchdog: Blocked in handler on ActivityManager (ActivityManager)

      说明ActivityManager这个线程被blocked了(ActivityManager是system_server的一个线程)

  

2. 查看ActivityManager线程的堆栈状态:

  "ActivityManager" prio=5 tid=15 Blocked

  at com.android.server.am.ActivityManagerService$MainHandler.handleMessage(ActivityManagerService.java:1784)

  - waiting to lock <0x1a4c832a> (a com.android.server.am.ActivityManagerService) held by thread 61

  该线程在等待锁<0x1a4c832a>,这个锁被thread 61所持有

  

3.查看thread 61的堆栈状态:

   "Binder_5" prio=5 tid=61 Native

  at android.app.IActivityController$Stub$Proxy.appCrashed(IActivityController.java:222)

  at com.android.server.am.ActivityManagerService.crashApplication(ActivityManagerService.java:12297)

  - locked <0x1a4c832a> (a com.android.server.am.ActivityManagerService)

  at com.android.server.am.ActivityManagerService.handleApplicationCrashInner(ActivityManagerService.java:11838)

  at com.android.server.am.ActivityManagerService.handleApplicationCrash(ActivityManagerService.java:11820)

  这里可以看到tid=61的线程是AMS中的一个binder线程,而这个binder线程正在处理app crash,即在crashApplication方法中。由于

  当前处于monkey测试状态,所以会进入ActivityController的appCrashed方法。大致猜测可能是monkey进程的appCrashed被blocked住了,所以

  AMS的crashApplication方法也被blocked住了。

  

4,下面看一下monkey进程,搜一下“appCrashed”关键字,有如下log:

    "Binder_3" prio=5 tid=13 Blocked

  at com.android.commands.monkey.Monkey$ActivityController.appCrashed(Monkey.java:330)

  - waiting to lock <0x12a7bb9b> (a com.android.commands.monkey.Monkey) held by thread 1

  at android.app.IActivityController$Stub.onTransact(IActivityController.java:92)

  at android.os.Binder.execTransact(Binder.java:446)

   果不其然,appCrashed方法在等待锁<0x12a7bb9b>,而这个锁被thread 1锁持有。

   

5.看一下thread 1:

   "main" prio=5 tid=1 Native

  at libcore.io.BlockGuardOs.read(BlockGuardOs.java:230)

  at libcore.io.IoBridge.read(IoBridge.java:512)

  at java.io.FileInputStream.read(FileInputStream.java:177)

  at java.io.InputStreamReader.read(InputStreamReader.java:231)

  - locked <@addr=0x12c518a0> (a java.lang.ProcessManager$ProcessInputStream)

  at java.io.BufferedReader.fillBuf(BufferedReader.java:145)

  at java.io.BufferedReader.readLine(BufferedReader.java:397)

  - locked <@addr=0x12c51ac0> (a java.io.InputStreamReader)

  at com.android.commands.monkey.Monkey.commandLineReport(Monkey.java:458)

  at com.android.commands.monkey.Monkey.getBugreport(Monkey.java:497)

  at com.android.commands.monkey.Monkey.runMonkeyCycles(Monkey.java:1078)

  看到这里我们就明白了,实际上是IO阻塞了。这里可以大致说一下:在monkey测试的时候,当遇到anr\app crash等异常

  情况时,monkey会把这些异常情况写入文件中以供我们分析。monkey在写文件时,是调用“bugreport”这个shell命令来获取当前

  系统各进程的各线程的堆栈情况和状态的,而bugreport会得到大量的信息,所以如果在monkey测试时连续遇到anr/crash,有可能会导致

  这个写文件的过程很长,这样AMS通知monkey的appCrashed的方法就会被blocked住,进而导致AMS被blocked住。

  

 综述:

    monkey测试时,由于连续遇到anr/crash,导致monkey在写bugreport信息到文件的时间(getBugreport)过长。这样如果再次发生anr/crash时,AMS调用monkey的appCrashed的方法

通知monkey当前又有anr/crash发生,但是由于appCrashed方法和getBugreport方法持有同一把锁(monkey对象),所以appCrashed就拿不到锁被blocked住,进而导致AMS的

crashApplication方法被blocked住。而crashApplication持有的所对象是AMS本身,这样就导致所有持有AMS对象为锁的线程都被blocked住,这里面包括ActivityManager线程。这样

watchdog在定期锁检查的时候,就发现ActivityManager线程被blocked了,就会杀死System_server导致系统重启。

所以:这是monkey测试本身的io操作导致的持锁过久,最终导致system_server被杀死的问题。这个bug不需要解。

转自:http://blog.csdn.net/stephen8341/article/details/52642991
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: