summaryrefslogtreecommitdiffstats
path: root/core/java/android/os/StrictMode.java
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@android.com>2010-10-11 11:31:15 -0700
committerBrad Fitzpatrick <bradfitz@android.com>2010-10-11 11:31:15 -0700
commit191cdf023c3c1ab441087a77f7881c7bb376613a (patch)
treecd3eb3d5abdf7eef5ac1dcd6728fbf61c994b806 /core/java/android/os/StrictMode.java
parent4e1658afb8a79aa03a5ca712b02b2a33fb00bf6d (diff)
downloadframeworks_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.java33
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;
}