Try to mitigate issue #31016187: system_server crash in ArraySet.
Instead of crashing, log a wtf and recover. This is not a problem in ArraySet, but caused by someone else using an ArraySet without protecting access to it. So whoever is calling at this point is not the cause, and it isn't worthwhile to let them crash. Change-Id: Iaefa4315b620c9fe24b31507e4aa47a8525c8540
This commit is contained in:
@@ -156,6 +156,7 @@ public final class ArraySet<E> implements Collection<E>, Set<E> {
|
|||||||
synchronized (ArraySet.class) {
|
synchronized (ArraySet.class) {
|
||||||
if (mTwiceBaseCache != null) {
|
if (mTwiceBaseCache != null) {
|
||||||
final Object[] array = mTwiceBaseCache;
|
final Object[] array = mTwiceBaseCache;
|
||||||
|
try {
|
||||||
mArray = array;
|
mArray = array;
|
||||||
mTwiceBaseCache = (Object[]) array[0];
|
mTwiceBaseCache = (Object[]) array[0];
|
||||||
mHashes = (int[]) array[1];
|
mHashes = (int[]) array[1];
|
||||||
@@ -164,12 +165,21 @@ public final class ArraySet<E> implements Collection<E>, Set<E> {
|
|||||||
if (DEBUG) Log.d(TAG, "Retrieving 2x cache " + mHashes
|
if (DEBUG) Log.d(TAG, "Retrieving 2x cache " + mHashes
|
||||||
+ " now have " + mTwiceBaseCacheSize + " entries");
|
+ " now have " + mTwiceBaseCacheSize + " entries");
|
||||||
return;
|
return;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
}
|
||||||
|
// Whoops! Someone trampled the array (probably due to not protecting
|
||||||
|
// their access with a lock). Our cache is corrupt; report and give up.
|
||||||
|
Slog.wtf(TAG, "Found corrupt ArraySet cache: [0]=" + array[0]
|
||||||
|
+ " [1]=" + array[1]);
|
||||||
|
mTwiceBaseCache = null;
|
||||||
|
mTwiceBaseCacheSize = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (size == BASE_SIZE) {
|
} else if (size == BASE_SIZE) {
|
||||||
synchronized (ArraySet.class) {
|
synchronized (ArraySet.class) {
|
||||||
if (mBaseCache != null) {
|
if (mBaseCache != null) {
|
||||||
final Object[] array = mBaseCache;
|
final Object[] array = mBaseCache;
|
||||||
|
try {
|
||||||
mArray = array;
|
mArray = array;
|
||||||
mBaseCache = (Object[]) array[0];
|
mBaseCache = (Object[]) array[0];
|
||||||
mHashes = (int[]) array[1];
|
mHashes = (int[]) array[1];
|
||||||
@@ -178,6 +188,14 @@ public final class ArraySet<E> implements Collection<E>, Set<E> {
|
|||||||
if (DEBUG) Log.d(TAG, "Retrieving 1x cache " + mHashes
|
if (DEBUG) Log.d(TAG, "Retrieving 1x cache " + mHashes
|
||||||
+ " now have " + mBaseCacheSize + " entries");
|
+ " now have " + mBaseCacheSize + " entries");
|
||||||
return;
|
return;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
}
|
||||||
|
// Whoops! Someone trampled the array (probably due to not protecting
|
||||||
|
// their access with a lock). Our cache is corrupt; report and give up.
|
||||||
|
Slog.wtf(TAG, "Found corrupt ArraySet cache: [0]=" + array[0]
|
||||||
|
+ " [1]=" + array[1]);
|
||||||
|
mBaseCache = null;
|
||||||
|
mBaseCacheSize = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user