From 73d6a821aeecd6003c70c32f7ae6c38f062c4290 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Mon, 29 Sep 2014 10:52:47 -0700 Subject: Work on issue #17656716: Unhandled exception in Window Manager Remove the checks for large parcel sizes. Those were triggering, and identifyng the area of the problem, but also cause a lot of trouble by making the unsafe deadlocky code there much more likely to deadlock. Add logging for strict mode IPCs, since those seem to be the problem. Only log when things look bad. Also add a log when battery stats are reset, to diagnose why they are getting reset when they shouldn't be. Change-Id: I588c858fb8d8c45f3c9c164ae2de9ae01547b304 --- core/java/android/app/ApplicationErrorReport.java | 12 ++++++++++++ core/java/android/os/Binder.java | 3 ++- core/java/android/os/StrictMode.java | 20 ++++++++++++++++++++ .../com/android/internal/os/BatteryStatsImpl.java | 3 +++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java index 8b132e063ebe..be4e80e8da8b 100644 --- a/core/java/android/app/ApplicationErrorReport.java +++ b/core/java/android/app/ApplicationErrorReport.java @@ -27,6 +27,7 @@ import android.os.Parcelable; import android.os.SystemProperties; import android.provider.Settings; import android.util.Printer; +import android.util.Slog; import com.android.internal.util.FastPrintWriter; import java.io.PrintWriter; @@ -378,6 +379,7 @@ public class ApplicationErrorReport implements Parcelable { * Save a CrashInfo instance to a parcel. */ public void writeToParcel(Parcel dest, int flags) { + int start = dest.dataPosition(); dest.writeString(exceptionClassName); dest.writeString(exceptionMessage); dest.writeString(throwFileName); @@ -385,6 +387,16 @@ public class ApplicationErrorReport implements Parcelable { dest.writeString(throwMethodName); dest.writeInt(throwLineNumber); dest.writeString(stackTrace); + int total = dest.dataPosition()-start; + if (total > 100*1024) { + Slog.d("Error", "ERR: exClass=" + exceptionClassName); + Slog.d("Error", "ERR: exMsg=" + exceptionMessage); + Slog.d("Error", "ERR: file=" + throwFileName); + Slog.d("Error", "ERR: class=" + throwClassName); + Slog.d("Error", "ERR: method=" + throwMethodName + " line=" + throwLineNumber); + Slog.d("Error", "ERR: stack=" + stackTrace); + Slog.d("Error", "ERR: TOTAL BYTES WRITTEN: " + (dest.dataPosition()-start)); + } } /** diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index cb5a31ccd219..f5fc0d70d5f4 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -49,6 +49,7 @@ public class Binder implements IBinder { * of classes can potentially create leaks. */ private static final boolean FIND_POTENTIAL_LEAKS = false; + private static final boolean CHECK_PARCEL_SIZE = false; static final String TAG = "Binder"; /** @@ -388,7 +389,7 @@ public class Binder implements IBinder { } static void checkParcel(IBinder obj, int code, Parcel parcel, String msg) { - if (parcel.dataSize() >= 800*1024) { + if (CHECK_PARCEL_SIZE && parcel.dataSize() >= 800*1024) { // Trying to send > 800k, this is way too much StringBuilder sb = new StringBuilder(); sb.append(msg); diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index ea71ad8c0563..4e9d1f096257 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -28,6 +28,7 @@ import android.util.ArrayMap; import android.util.Log; import android.util.Printer; import android.util.Singleton; +import android.util.Slog; import android.view.IWindowManager; import com.android.internal.os.RuntimeInit; @@ -40,6 +41,7 @@ import dalvik.system.VMDebug; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -1688,7 +1690,13 @@ public final class StrictMode { } else { p.writeInt(violations.size()); for (int i = 0; i < violations.size(); ++i) { + int start = p.dataPosition(); violations.get(i).writeToParcel(p, 0 /* unused flags? */); + int size = p.dataPosition()-start; + if (size > 100*1024) { + Slog.d(TAG, "Wrote violation #" + i + " of " + violations.size() + ": " + + (p.dataPosition()-start) + " bytes"); + } } if (LOG_V) Log.d(TAG, "wrote violations to response parcel; num=" + violations.size()); violations.clear(); // somewhat redundant, as we're about to null the threadlocal @@ -2176,6 +2184,7 @@ public final class StrictMode { */ public void writeToParcel(Parcel dest, int flags) { crashInfo.writeToParcel(dest, flags); + int start = dest.dataPosition(); dest.writeInt(policy); dest.writeInt(durationMillis); dest.writeInt(violationNumThisLoop); @@ -2184,6 +2193,17 @@ public final class StrictMode { dest.writeLong(numInstances); dest.writeString(broadcastIntentAction); dest.writeStringArray(tags); + int total = dest.dataPosition()-start; + if (total > 100*1024) { + Slog.d(TAG, "VIO: policy=" + policy + " dur=" + durationMillis + + " numLoop=" + violationNumThisLoop + + " anim=" + numAnimationsRunning + + " uptime=" + violationUptimeMillis + + " numInst=" + numInstances); + Slog.d(TAG, "VIO: action=" + broadcastIntentAction); + Slog.d(TAG, "VIO: tags=" + Arrays.toString(tags)); + Slog.d(TAG, "VIO: TOTAL BYTES WRITTEN: " + (dest.dataPosition()-start)); + } } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 81705be8478b..42fc6132add4 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -6748,6 +6748,9 @@ public final class BatteryStatsImpl extends BatteryStats { || getLowDischargeAmountSinceCharge() >= 60) || (getHighDischargeAmountSinceCharge() >= 60 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER)) { + Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus + + " lowAmount=" + getLowDischargeAmountSinceCharge() + + " highAmount=" + getHighDischargeAmountSinceCharge()); // Before we write, collect a snapshot of the final aggregated // stats to be reported in the next checkin. Only do this if we have // a sufficient amount of data to make it interesting. -- cgit v1.2.3-59-g8ed1b