android 8.1 上,报了一个手机重启。
查看android event log, 查询关键字 am_crash, 发现问题出现的时间点上有个 NullPointerException
16:16:12.278 1000 3277 3456 I am_crash: [3277,0,system_server,-1,java.lang.NullPointerException,Attempt to invoke virtual method 'void com.android.bluetooth.gatt.AdvertiseManager.stopAdvertisingSets()' on a null object reference,Parcel.java,1949]
main log 上可以看到, system server 已经在垂死挣扎中。
16:16:12.446 10037 32271 32271 E AndroidRuntime: DeadSystemException: The system died; earlier logs will point to the root cause
以上打印log的代码位置如下:
frameworks/base/core/java/android/util/Log.java
/**
* Helper function for long messages. Uses the LineBreakBufferedWriter to break
* up long messages and stacktraces along newlines, but tries to write in large
* chunks. This is to avoid truncation.
* @hide
*/
public static int printlns(int bufID, int priority, String tag, String msg,
Throwable tr) {
ImmediateLogWriter logWriter = new ImmediateLogWriter(bufID, priority, tag);
// Acceptable buffer size. Get the native buffer size, subtract two zero terminators,
// and the length of the tag.
// Note: we implicitly accept possible truncation for Modified-UTF8 differences. It
// is too expensive to compute that ahead of time.
int bufferSize = PreloadHolder.LOGGER_ENTRY_MAX_PAYLOAD // Base.
- 2 // Two terminators.
- (tag != null ? tag.length() : 0) // Tag length.
- 32; // Some slack.
// At least assume you can print *some* characters (tag is not too large).
bufferSize = Math.max(bufferSize, 100);
LineBreakBufferedWriter lbbw = new LineBreakBufferedWriter(logWriter, bufferSize);
lbbw.println(msg);
if (tr != null) {
// This is to reduce the amount of log spew that apps do in the non-error
// condition of the network being unavailable.
Throwable t = tr;
while (t != null) {
if (t instanceof UnknownHostException) {
break;
}
if (t instanceof DeadSystemException) {
lbbw.println("DeadSystemException: The system died; "
+ "earlier logs will point to the root cause");
break;
}
t = t.getCause();
}
if (t == null) {
tr.printStackTrace(lbbw);
}
}
lbbw.flush();
return logWriter.getWritten();
}
以下是发生问题时的BackTrace,问题就是一个 NullPointerException,跟 BT 有关。
16:16:12.278 1000 3277 3456 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: android.io
16:16:12.278 1000 3277 3456 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.android.bluetooth.gatt.AdvertiseManager.stopAdvertisingSets()' on a null object reference
16:16:12.278 1000 3277 3456 E AndroidRuntime: at android.os.Parcel.readException(Parcel.java:1949)
16:16:12.278 1000 3277 3456 E AndroidRuntime: at android.os.Parcel.readException(Parcel.java:1889)
16:16:12.278 1000 3277 3456 E AndroidRuntime: at android.bluetooth.IBluetoothGatt$Stub$Proxy.unregAll(IBluetoothGatt.java:1855)
16:16:12.278 1000 3277 3456 E AndroidRuntime: at com.android.server.BluetoothManagerService.sendBrEdrDownCallback(BluetoothManagerService.java:794)
16:16:12.278 1000 3277 3456 E AndroidRuntime: at com.android.server.BluetoothManagerService.bluetoothStateChangeHandler(BluetoothManagerService.java:2076)
16:16:12.278 1000 3277 3456 E AndroidRuntime: at com.android.server.BluetoothManagerService.-wrap7(Unknown Source:0)
16:16:12.278 1000 3277 3456 E AndroidRuntime: at com.android.server.BluetoothManagerService$BluetoothHandler.handleMessage(BluetoothManagerService.java:1697)
16:16:12.278 1000 3277 3456 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:105)
16:16:12.278 1000 3277 3456 E AndroidRuntime: at android.os.Looper.loop(Looper.java:164)
16:16:12.278 1000 3277 3456 E AndroidRuntime: at android.os.HandlerThread.run(HandlerThread.java:65)
16:16:12.278 1000 3277 3456 E AndroidRuntime: at com.android.server.ServiceThread.run(ServiceThread.java:46)
16:16:12.280 1000 3277 3277 I chatty : uid=1000 system_server expire 1 line
对应code:
frameworks/base/services/core/java/com/android/server/BluetoothManagerService.java
769 /**
770 * Inform BluetoothAdapter instances that BREDR part is down
771 * and turn off all service and stack if no LE app needs it
772 */
773 private void sendBrEdrDownCallback() {
774 if (DBG) Slog.d(TAG,"Calling sendBrEdrDownCallback callbacks");
775
776 if (mBluetooth == null) {
777 Slog.w(TAG, "Bluetooth handle is null");
778 return;
779 }
780
781 if (isBleAppPresent()) {
782 // Need to stay at BLE ON. Disconnect all Gatt connections
783 try {
784 mBluetoothGatt.unregAll();
785 } catch (RemoteException e) {
786 Slog.e(TAG, "Unable to disconnect all apps.", e);
787 }
788 } else {
789 try {
790 mBluetoothLock.readLock().lock();
791 if (mBluetooth != null) mBluetooth.onBrEdrDown();
792 } catch (RemoteException e) {
793 Slog.e(TAG, "Call to onBrEdrDown() failed.", e);
794 } finally {
795 mBluetoothLock.readLock().unlock();
796 }
797 }
798
799 }
BluetoothManagerService.java 794行已经在走异常流程。
省略分析...
属于android 原生问题,最后发现已经有patch,传送门
https://android-review.googlesource.com/
end.