1. 程式人生 > >Android ANR問題分析

Android ANR問題分析

備註:展訊平臺

案例分析:

1.等待鎖引起的ANR問題

現在遇到一個Monkey跑出來的Camera bug.

1).找出ANR發生的時間

一般情況下,拿到測試提供的log之後,需要在trace目錄下開啟ANR log檔案(這裡有可能有很多anr日誌檔案,找到和你有關的就行,如果沒有和你有關係的,請轉給對應的模組owner)。如下是我在分析該bug時的anr日誌檔案:

-rwxrwxrwx 1 root root 1439284 Jul 25 06:35 0001.20120101-115416.856.anr*
-rwxrwxrwx 1 root root 820120 Jul 25 06:35 0001.20120102-000727.046.tombstone*
-rwxrwxrwx 1 root root 2318604 Jul 25 06:35 0002.20120101-153245.085.anr*
-rwxrwxrwx 1 root root 2296634 Jul 25 06:35 0003.20120101-153252.049.anr*
-rwxrwxrwx 1 root root 1715999 Jul 25 06:35 0004.20120101-153335.657.anr*

查詢後發現Camera的anr日誌就是第一個,開啟後可以發現開頭的地方就是camera應用anr了,可以發現發生anr的時間是在2012-01-01 03:54:11發生的。

ylog.anr 000 [ cat /data/ylog/traces.txt.ylog ] [01-01 11:54:16.966]-
—– pid 22910 at 2012-01-01 03:54:11 —–
Cmd line: com.android.camera2

2).初步定位問題發生的原因

在anr日誌檔案中搜索Blocked關鍵字(可能有很多Blocked關鍵字,但是要找到和Camera有關係的那個)

“pool-2-thread-6” prio=5 tid=21 Blocked
| group=”main” sCount=1 dsCount=0 obj=0x12c0aa60 self=0x754f7dac00
| sysTid=22940 nice=10 cgrp=bg_non_interactive sched=0/0 handle=0x753f532450
| state=S schedstat=( 38854895 3200374253 296 ) utm=2 stm=1 core=0 HZ=100
| stack=0x753f430000-0x753f432000 stackSize=1037KB
| held mutexes=
at android.hardware.camera2.CameraManager.getCameraIdList(CameraManager.java:98)
- waiting to lock <0x07410fc0> (a java.lang.Object) held by thread 24//這個地方我們明顯可以看到,這個地方在等一個鎖,而且是被24號執行緒鎖住的。那我們去24號執行緒看一下(這裡一定要非常注意鎖的地址是0x07410fc0,你也可以直接搜尋這個地址,找到使用這個鎖的地方)。
at com.android.ex.camera2.portability.AndroidCamera2AgentImpl.updateCameraDevices(AndroidCamera2AgentImpl.java:122)
at com.android.ex.camera2.portability.AndroidCamera2AgentImpl.(AndroidCamera2AgentImpl.java:112)
at com.android.ex.camera2.portability.SprdAndroidCamera2AgentImpl.(SprdAndroidCamera2AgentImpl.java:38)
at com.android.ex.camera2.portability.CameraAgentFactory.getAndroidCameraAgent(CameraAgentFactory.java:129)
- locked <0x080064f9> (a java.lang.Class

3).原始碼追蹤

frameworks/base/core/java/android/hardware/camera2/CameraManager.java
下面可以看到這段程式碼是在synchronized中包含的,可以知道,這個時候已經將該段互斥程式碼鎖住了,這裡
已經鎖住了mLock這個鎖。

289    private CameraDevice openCameraDeviceUserAsync(String cameraId,
290            CameraDevice.StateCallback callback, Handler handler)
291            throws CameraAccessException {
292        CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
   synchronized (mLock) {
339                if (supportsCamera2ApiLocked(cameraId)) {
340                    // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
341                    ICameraService cameraService =
                       CameraManagerGlobal.get().getCameraService();
342                    if (cameraService == null) {
343                        throw new ServiceSpecificException(
344                            ICameraService.ERROR_DISCONNECTED,
345                            "Camera service is currently unavailable");
346                    }
347                    cameraUser = cameraService.connectDevice(callbacks, id,
348                            mContext.getOpPackageName(), USE_CALLING_UID);
....
  }

導致這個原因就是上一次CloseCamera沒有成功,上一次的CameraClient物件仍然駐留在CameraServie 中,CameraService就會提示有多個客戶端使用Camera,所以就一直OpenCamera不成功,導致這個執行緒一直持有mLock這個鎖,當其它執行緒執行這段程式碼就只有等待鎖的份了。
  所以應該分析的問題是,底層為什麼沒有成功關閉Camera,然後分析問題是不是你的,不是就要流轉到其它組。

2.系統性能引起的ANR問題

3.UI主執行緒耗時操作引起的ANR問題

上面部分待後續遇到了再來完善。