Resource Leakage in Android Java Apk
Bug: Keep on resetting BT adapter cause Android crash
Bug description: In GTV/Honeycomb’s System Setting UI, keep on turning on/off Bluetooth for about 270 times, Android will crash, and UI restart from blackscreen.
My analyze: First thing is to located where Android system crashed from logcat, there must be something related to zygote, then I found this:
1
|
|
Above that I found a fatal error message:
1
|
|
then all system service died like below:
1
|
|
Tracing down the fatal error message in Android XRef, the error occurs when creating a new Looper instance, in Honeycomb/frameworks/base/libs/utils/Looper.cpp, where 3 new pips need to be created for one new Looper object. So I guess the isssue is kind of file/socket/pipe handle leakage issue, to verify this, compare “lsof” result after turn on/off Bluetooth once, I can see there’s 3 newly opened pipes in system_service everytime I performed a turn on/off Bluetooth. Then I found from website that someone reported similar issue on Android Bug List
1 2 3 4 5 6 7 8 |
|
The symptom is quite clear now, but how to locate leakage position in Android?
The first clue is that Looper object is used for Android Handler object, it’s hard to dump call stack in Android native C++ service, but it’s easy to do that in Java. So I added a dump stack in Handler’s construction method, caught below message when I turn on Bluetooth:
1 2 3 4 5 6 7 8 9 10 |
|
After doing some source code search, I reached the place in BluetoothService.java when problem occurs: When turn off BT, BluetoothService will do:
1 2 3 |
|
Then when turn on BT again, it will do:
1 2 3 4 5 |
|
Problem here is, we only need do a reset when turn off BT, then we can reuse the BluetoothDeviceProfileState object after we turn it on again, but Android removed it instead, then need to create a new BluetoothDeviceProfileState object next time. If we did not remove the object every time we turn off BT, then the issue disappeared.
My comments: For Java class who claims system resource in its construction method, we must declare corresponding interface to release them, GC can not do this job for us.