diff options
13 files changed, 140 insertions, 62 deletions
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 0e561bd..0ee8d86f 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -1725,10 +1725,25 @@ public final class StrictMode { for (int i = 0; i < numViolations; ++i) { if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i); ViolationInfo info = new ViolationInfo(p, !currentlyGathering); - if (info.crashInfo.stackTrace.length() > 5000) { - RuntimeException here = new RuntimeException("here"); - here.fillInStackTrace(); - Slog.w(TAG, "Stack is getting large: " + info.crashInfo.stackTrace, here); + if (info.crashInfo.stackTrace.length() > 10000) { + // 10000 characters is way too large for this to be any sane kind of + // strict mode collection of stacks. We've had a problem where we leave + // strict mode violations associated with the thread, and it keeps tacking + // more and more stacks on to the violations. Looks like we're in this casse, + // so we'll report it and bail on all of the current strict mode violations + // we currently are maintaining for this thread. + // First, drain the remaining violations from the parcel. + while (i < numViolations) { + info = new ViolationInfo(p, !currentlyGathering); + i++; + } + // Next clear out all gathered violations. + clearGatheredViolations(); + // Now report the problem. + Slog.wtfStack(TAG, "Stack is too large: numViolations=" + numViolations + + " policy=#" + Integer.toHexString(policyMask) + + " front=" + info.crashInfo.stackTrace.substring(256)); + return; } info.crashInfo.stackTrace += "# via Binder call with stack:\n" + ourStack; BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); diff --git a/core/java/android/util/Slog.java b/core/java/android/util/Slog.java index 7a5fd50..e92b846 100644 --- a/core/java/android/util/Slog.java +++ b/core/java/android/util/Slog.java @@ -73,18 +73,38 @@ public final class Slog { msg + '\n' + Log.getStackTraceString(tr)); } + /** + * Like {@link Log#wtf(String, String)}, but will never cause the caller to crash, and + * will always be handled asynchronously. Primarily for use by coding running within + * the system process. + */ public static int wtf(String tag, String msg) { return Log.wtf(Log.LOG_ID_SYSTEM, tag, msg, null, false, true); } + /** + * Like {@link Log#wtfStack(String, String)}, but will never cause the caller to crash, and + * will always be handled asynchronously. Primarily for use by coding running within + * the system process. + */ public static int wtfStack(String tag, String msg) { return Log.wtf(Log.LOG_ID_SYSTEM, tag, msg, null, true, true); } + /** + * Like {@link Log#wtf(String, Throwable)}, but will never cause the caller to crash, + * and will always be handled asynchronously. Primarily for use by coding running within + * the system process. + */ public static int wtf(String tag, Throwable tr) { return Log.wtf(Log.LOG_ID_SYSTEM, tag, tr.getMessage(), tr, false, true); } + /** + * Like {@link Log#wtf(String, String, Throwable)}, but will never cause the caller to crash, + * and will always be handled asynchronously. Primarily for use by coding running within + * the system process. + */ public static int wtf(String tag, String msg, Throwable tr) { return Log.wtf(Log.LOG_ID_SYSTEM, tag, msg, tr, false, true); } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index ba5d11d..8084eda 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -351,8 +351,11 @@ public class SettingsProvider extends ContentProvider { } public void onEvent(int event, String path) { - int modsInFlight = sKnownMutationsInFlight.get(mUserHandle).get(); - if (modsInFlight > 0) { + final AtomicInteger mutationCount; + synchronized (SettingsProvider.this) { + mutationCount = sKnownMutationsInFlight.get(mUserHandle); + } + if (mutationCount != null && mutationCount.get() > 0) { // our own modification. return; } @@ -952,8 +955,13 @@ public class SettingsProvider extends ContentProvider { checkWritePermissions(args); SettingsCache cache = cacheForTable(callingUser, args.table); - final AtomicInteger mutationCount = sKnownMutationsInFlight.get(callingUser); - mutationCount.incrementAndGet(); + final AtomicInteger mutationCount; + synchronized (this) { + mutationCount = sKnownMutationsInFlight.get(callingUser); + } + if (mutationCount != null) { + mutationCount.incrementAndGet(); + } DatabaseHelper dbH = getOrEstablishDatabase( TABLE_GLOBAL.equals(args.table) ? UserHandle.USER_OWNER : callingUser); SQLiteDatabase db = dbH.getWritableDatabase(); @@ -969,7 +977,9 @@ public class SettingsProvider extends ContentProvider { db.setTransactionSuccessful(); } finally { db.endTransaction(); - mutationCount.decrementAndGet(); + if (mutationCount != null) { + mutationCount.decrementAndGet(); + } } sendNotify(uri, callingUser); @@ -1105,12 +1115,19 @@ public class SettingsProvider extends ContentProvider { return Uri.withAppendedPath(url, name); } - final AtomicInteger mutationCount = sKnownMutationsInFlight.get(desiredUserHandle); - mutationCount.incrementAndGet(); + final AtomicInteger mutationCount; + synchronized (this) { + mutationCount = sKnownMutationsInFlight.get(callingUser); + } + if (mutationCount != null) { + mutationCount.incrementAndGet(); + } DatabaseHelper dbH = getOrEstablishDatabase(desiredUserHandle); SQLiteDatabase db = dbH.getWritableDatabase(); final long rowId = db.insert(args.table, null, initialValues); - mutationCount.decrementAndGet(); + if (mutationCount != null) { + mutationCount.decrementAndGet(); + } if (rowId <= 0) return null; SettingsCache.populate(cache, initialValues); // before we notify @@ -1137,12 +1154,19 @@ public class SettingsProvider extends ContentProvider { } checkWritePermissions(args); - final AtomicInteger mutationCount = sKnownMutationsInFlight.get(callingUser); - mutationCount.incrementAndGet(); + final AtomicInteger mutationCount; + synchronized (this) { + mutationCount = sKnownMutationsInFlight.get(callingUser); + } + if (mutationCount != null) { + mutationCount.incrementAndGet(); + } DatabaseHelper dbH = getOrEstablishDatabase(callingUser); SQLiteDatabase db = dbH.getWritableDatabase(); int count = db.delete(args.table, args.where, args.args); - mutationCount.decrementAndGet(); + if (mutationCount != null) { + mutationCount.decrementAndGet(); + } if (count > 0) { invalidateCache(callingUser, args.table); // before we notify sendNotify(url, callingUser); @@ -1170,12 +1194,19 @@ public class SettingsProvider extends ContentProvider { checkWritePermissions(args); checkUserRestrictions(initialValues.getAsString(Settings.Secure.NAME), callingUser); - final AtomicInteger mutationCount = sKnownMutationsInFlight.get(callingUser); - mutationCount.incrementAndGet(); + final AtomicInteger mutationCount; + synchronized (this) { + mutationCount = sKnownMutationsInFlight.get(callingUser); + } + if (mutationCount != null) { + mutationCount.incrementAndGet(); + } DatabaseHelper dbH = getOrEstablishDatabase(callingUser); SQLiteDatabase db = dbH.getWritableDatabase(); int count = db.update(args.table, initialValues, args.where, args.args); - mutationCount.decrementAndGet(); + if (mutationCount != null) { + mutationCount.decrementAndGet(); + } if (count > 0) { invalidateCache(callingUser, args.table); // before we notify sendNotify(url, callingUser); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index d5b6813..4a10b73 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -27,7 +27,6 @@ import static com.android.internal.util.XmlUtils.writeBooleanAttribute; import static com.android.internal.util.XmlUtils.writeIntAttribute; import static com.android.internal.util.XmlUtils.writeLongAttribute; import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; -import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; @@ -4958,7 +4957,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } } catch (InterruptedException e) { - Log.wtf(TAG, e); + Slog.wtf(TAG, e); } } @@ -4998,7 +4997,7 @@ public final class ActivityManagerService extends ActivityManagerNative observer.wait(200); // Wait for write-close, give up after 200msec } } catch (InterruptedException e) { - Log.wtf(TAG, e); + Slog.wtf(TAG, e); } } @@ -7918,9 +7917,9 @@ public final class ActivityManagerService extends ActivityManagerNative } catch (FileNotFoundException e) { // Missing grants is okay } catch (IOException e) { - Log.wtf(TAG, "Failed reading Uri grants", e); + Slog.wtf(TAG, "Failed reading Uri grants", e); } catch (XmlPullParserException e) { - Log.wtf(TAG, "Failed reading Uri grants", e); + Slog.wtf(TAG, "Failed reading Uri grants", e); } finally { IoUtils.closeQuietly(fis); } @@ -11713,17 +11712,10 @@ public final class ActivityManagerService extends ActivityManagerNative * @param crashInfo describing the context of the error * @return true if the process should exit immediately (WTF is fatal) */ - public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, + public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, final ApplicationErrorReport.CrashInfo crashInfo) { - final ProcessRecord r = findAppProcess(app, "WTF"); - final String processName = app == null ? "system_server" - : (r == null ? "unknown" : r.processName); - - EventLog.writeEvent(EventLogTags.AM_WTF, - UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), - processName, - r == null ? -1 : r.info.flags, - tag, crashInfo.exceptionMessage); + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); if (system) { // If this is coming from the system, we could very well have low-level @@ -11731,14 +11723,14 @@ public final class ActivityManagerService extends ActivityManagerNative // never want this to become fatal, so there is that too. mHandler.post(new Runnable() { @Override public void run() { - addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, - crashInfo); + handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); } }); return false; } - addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); + final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, + crashInfo); if (r != null && r.pid != Process.myPid() && Settings.Global.getInt(mContext.getContentResolver(), @@ -11750,6 +11742,20 @@ public final class ActivityManagerService extends ActivityManagerNative } } + ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, + final ApplicationErrorReport.CrashInfo crashInfo) { + final ProcessRecord r = findAppProcess(app, "WTF"); + final String processName = app == null ? "system_server" + : (r == null ? "unknown" : r.processName); + + EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, + processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); + + addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); + + return r; + } + /** * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) * @return the corresponding {@link ProcessRecord} object, or null if none could be found diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 4e554eb..e01b983 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -901,7 +901,7 @@ public final class BroadcastQueue { Slog.w(TAG, "Exception when sending broadcast to " + r.curComponent, e); } catch (RuntimeException e) { - Log.wtf(TAG, "Failed sending broadcast to " + Slog.wtf(TAG, "Failed sending broadcast to " + r.curComponent + " with " + r.intent, e); // If some unexpected exception happened, just skip // this broadcast. At this point we are not in the call diff --git a/services/core/java/com/android/server/am/UriPermission.java b/services/core/java/com/android/server/am/UriPermission.java index 91daf77..650a837 100644 --- a/services/core/java/com/android/server/am/UriPermission.java +++ b/services/core/java/com/android/server/am/UriPermission.java @@ -257,7 +257,7 @@ final class UriPermission { */ void removeReadOwner(UriPermissionOwner owner) { if (!mReadOwners.remove(owner)) { - Log.wtf(TAG, "Unknown read owner " + owner + " in " + this); + Slog.wtf(TAG, "Unknown read owner " + owner + " in " + this); } if (mReadOwners.size() == 0) { mReadOwners = null; @@ -282,7 +282,7 @@ final class UriPermission { */ void removeWriteOwner(UriPermissionOwner owner) { if (!mWriteOwners.remove(owner)) { - Log.wtf(TAG, "Unknown write owner " + owner + " in " + this); + Slog.wtf(TAG, "Unknown write owner " + owner + " in " + this); } if (mWriteOwners.size() == 0) { mWriteOwners = null; diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 43c01cd..97748e8 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -448,7 +448,7 @@ public final class DisplayManagerService extends SystemService { mWifiDisplayAdapter.requestStopScanLocked(); } } else if (mWifiDisplayScanRequestCount < 0) { - Log.wtf(TAG, "mWifiDisplayScanRequestCount became negative: " + Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: " + mWifiDisplayScanRequestCount); mWifiDisplayScanRequestCount = 0; } diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index c106546..d5858a5 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -325,9 +325,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub { } catch (FileNotFoundException e) { // Missing sessions are okay, probably first boot } catch (IOException e) { - Log.wtf(TAG, "Failed reading install sessions", e); + Slog.wtf(TAG, "Failed reading install sessions", e); } catch (XmlPullParserException e) { - Log.wtf(TAG, "Failed reading install sessions", e); + Slog.wtf(TAG, "Failed reading install sessions", e); } finally { IoUtils.closeQuietly(fis); } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 4e33ca8..9473495 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -1178,12 +1178,14 @@ final class Settings { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading stopped packages: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", + e); } catch (java.io.IOException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", + e); } } @@ -1272,7 +1274,8 @@ final class Settings { // might have been corrupted. if (!backupFile.exists()) { if (!userPackagesStateFile.renameTo(backupFile)) { - Log.wtf(PackageManagerService.TAG, "Unable to backup user packages state file, " + Slog.wtf(PackageManagerService.TAG, + "Unable to backup user packages state file, " + "current changes will be lost at reboot"); return; } @@ -1379,7 +1382,7 @@ final class Settings { // Done, all is good! return; } catch(java.io.IOException e) { - Log.wtf(PackageManagerService.TAG, + Slog.wtf(PackageManagerService.TAG, "Unable to write package manager user packages state, " + " current changes will be lost at reboot", e); } @@ -1485,12 +1488,14 @@ final class Settings { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading stopped packages: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", + e); } catch (java.io.IOException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager stopped packages", + e); } } @@ -1507,7 +1512,8 @@ final class Settings { // might have been corrupted. if (!mBackupSettingsFilename.exists()) { if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) { - Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, " + Slog.wtf(PackageManagerService.TAG, + "Unable to backup package manager settings, " + " current changes will be lost at reboot"); return; } @@ -1698,7 +1704,7 @@ final class Settings { str.close(); journal.commit(); } catch (Exception e) { - Log.wtf(TAG, "Failed to write packages.list", e); + Slog.wtf(TAG, "Failed to write packages.list", e); IoUtils.closeQuietly(str); journal.rollback(); } @@ -1707,16 +1713,16 @@ final class Settings { return; } catch(XmlPullParserException e) { - Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " + Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " + "current changes will be lost at reboot", e); } catch(java.io.IOException e) { - Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " + Slog.wtf(PackageManagerService.TAG, "Unable to write package manager settings, " + "current changes will be lost at reboot", e); } // Clean up partially written files if (mSettingsFilename.exists()) { if (!mSettingsFilename.delete()) { - Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " + Slog.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: " + mSettingsFilename); } } @@ -1984,7 +1990,7 @@ final class Settings { mReadMessages.append("No start tag found in settings file\n"); PackageManagerService.reportSettingsProblem(Log.WARN, "No start tag found in package manager settings"); - Log.wtf(PackageManagerService.TAG, + Slog.wtf(PackageManagerService.TAG, "No start tag found in package manager settings"); return false; } @@ -2097,12 +2103,12 @@ final class Settings { } catch (XmlPullParserException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); } catch (java.io.IOException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); - Log.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); + Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e); } final int N = mPendingPackages.size(); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 7ad5542..52807c0 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -2170,7 +2170,7 @@ public final class PowerManagerService extends SystemService t.start(); t.join(); } catch (InterruptedException e) { - Log.wtf(TAG, e); + Slog.wtf(TAG, e); } } diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index da5cfda..69d3191 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -632,7 +632,7 @@ public class WindowAnimator { mService.mWatermark.drawIfNeeded(); } } catch (RuntimeException e) { - Log.wtf(TAG, "Unhandled exception in Window Manager", e); + Slog.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { SurfaceControl.closeTransaction(); if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 41574ca..467b9a4 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -8652,7 +8652,7 @@ public class WindowManagerService extends IWindowManager.Stub } } } catch (RuntimeException e) { - Log.wtf(TAG, "Unhandled exception while force removing for memory", e); + Slog.wtf(TAG, "Unhandled exception while force removing for memory", e); } try { @@ -8677,7 +8677,7 @@ public class WindowManagerService extends IWindowManager.Stub } } catch (RuntimeException e) { mInLayout = false; - Log.wtf(TAG, "Unhandled exception while laying out windows", e); + Slog.wtf(TAG, "Unhandled exception while laying out windows", e); } Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); @@ -9762,7 +9762,7 @@ public class WindowManagerService extends IWindowManager.Stub mDisplayManagerInternal.performTraversalInTransactionFromWindowManager(); } catch (RuntimeException e) { - Log.wtf(TAG, "Unhandled exception in Window Manager", e); + Slog.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index f339dba..92ad1ad 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -272,7 +272,7 @@ public final class SystemServer { private void reportWtf(String msg, Throwable e) { Slog.w(TAG, "***********************************************"); - Log.wtf(TAG, "BOOT FAILURE " + msg, e); + Slog.wtf(TAG, "BOOT FAILURE " + msg, e); } private void performPendingShutdown() { |