diff options
author | Brad Fitzpatrick <bradfitz@android.com> | 2010-10-11 11:31:15 -0700 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@android.com> | 2010-10-11 11:31:15 -0700 |
commit | 191cdf023c3c1ab441087a77f7881c7bb376613a (patch) | |
tree | cd3eb3d5abdf7eef5ac1dcd6728fbf61c994b806 /core/java/android/os/StrictMode.java | |
parent | 4e1658afb8a79aa03a5ca712b02b2a33fb00bf6d (diff) | |
download | frameworks_base-191cdf023c3c1ab441087a77f7881c7bb376613a.zip frameworks_base-191cdf023c3c1ab441087a77f7881c7bb376613a.tar.gz frameworks_base-191cdf023c3c1ab441087a77f7881c7bb376613a.tar.bz2 |
StrictMode: check max-offenses-per-loop earlier, before allocations
Previously a tight loop of StrictMode violations would still allocate
Exception objects and populate their stack frames, just to orphan them
later when checking the max-10-violations-per-loop constraint.
With this patch, we do that check _before_ allocating any memory.
Change-Id: Iae96aba33f8fcc6a8ec5838a231aecc08e95122d
Diffstat (limited to 'core/java/android/os/StrictMode.java')
-rw-r--r-- | core/java/android/os/StrictMode.java | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 9494a06..c185007 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -104,6 +104,10 @@ public final class StrictMode { // Only show an annoying dialog at most every 30 seconds private static final long MIN_DIALOG_INTERVAL_MS = 30000; + // How many offending stacks to keep track of (and time) per loop + // of the Looper. + private static final int MAX_OFFENSES_PER_LOOP = 10; + // Thread-policy: /** @@ -680,6 +684,17 @@ public final class StrictMode { } } + private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed = + new ThreadLocal<ArrayList<ViolationInfo>>() { + @Override protected ArrayList<ViolationInfo> initialValue() { + return new ArrayList<ViolationInfo>(); + } + }; + + private static boolean tooManyViolationsThisLoop() { + return violationsBeingTimed.get().size() >= MAX_OFFENSES_PER_LOOP; + } + private static class AndroidBlockGuardPolicy implements BlockGuard.Policy { private int mPolicyMask; @@ -707,6 +722,9 @@ public final class StrictMode { if ((mPolicyMask & DETECT_DISK_WRITE) == 0) { return; } + if (tooManyViolationsThisLoop()) { + return; + } BlockGuard.BlockGuardPolicyException e = new StrictModeDiskWriteViolation(mPolicyMask); e.fillInStackTrace(); startHandlingViolationException(e); @@ -717,6 +735,9 @@ public final class StrictMode { if ((mPolicyMask & DETECT_DISK_READ) == 0) { return; } + if (tooManyViolationsThisLoop()) { + return; + } BlockGuard.BlockGuardPolicyException e = new StrictModeDiskReadViolation(mPolicyMask); e.fillInStackTrace(); startHandlingViolationException(e); @@ -727,6 +748,9 @@ public final class StrictMode { if ((mPolicyMask & DETECT_NETWORK) == 0) { return; } + if (tooManyViolationsThisLoop()) { + return; + } BlockGuard.BlockGuardPolicyException e = new StrictModeNetworkViolation(mPolicyMask); e.fillInStackTrace(); startHandlingViolationException(e); @@ -747,13 +771,6 @@ public final class StrictMode { handleViolationWithTimingAttempt(info); } - private static final ThreadLocal<ArrayList<ViolationInfo>> violationsBeingTimed = - new ThreadLocal<ArrayList<ViolationInfo>>() { - @Override protected ArrayList<ViolationInfo> initialValue() { - return new ArrayList<ViolationInfo>(); - } - }; - // Attempts to fill in the provided ViolationInfo's // durationMillis field if this thread has a Looper we can use // to measure with. We measure from the time of violation @@ -780,7 +797,7 @@ public final class StrictMode { MessageQueue queue = Looper.myQueue(); final ArrayList<ViolationInfo> records = violationsBeingTimed.get(); - if (records.size() >= 10) { + if (records.size() >= MAX_OFFENSES_PER_LOOP) { // Not worth measuring. Too many offenses in one loop. return; } |