Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 904e5961 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by gitbuildkicker
Browse files

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
(cherry picked from commit 92aa4b2b)
(cherry picked from commit dd28b7b5)
parent 71c5b449
Loading
Loading
Loading
Loading
+34 −16
Original line number Original line Diff line number Diff line
@@ -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;
                }
                }
            }
            }
        }
        }