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

Commit 0644bcb7 authored by Siim Sammul's avatar Siim Sammul Committed by Android (Google) Code Review
Browse files

Merge "Add rate limiting to addTombstoneToDropbox." into tm-dev

parents 7fc26f8e 7c47347a
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.XmlUtils;
import com.android.server.am.DropboxRateLimiter;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -308,19 +309,31 @@ public class BootReceiver extends BroadcastReceiver {
        writeTimestamps(timestamps);
    }

    private static final DropboxRateLimiter sDropboxRateLimiter = new DropboxRateLimiter();

    /**
     * Add a tombstone to the DropBox.
     *
     * @param ctx Context
     * @param tombstone path to the tombstone
     * @param proto whether the tombstone is stored as proto
     * @param processName the name of the process corresponding to the tombstone
     */
    public static void addTombstoneToDropBox(Context ctx, File tombstone, boolean proto) {
    public static void addTombstoneToDropBox(
                Context ctx, File tombstone, boolean proto, String processName) {
        final DropBoxManager db = ctx.getSystemService(DropBoxManager.class);
        if (db == null) {
            Slog.e(TAG, "Can't log tombstone: DropBoxManager not available");
            return;
        }

        // Check if we should rate limit and abort early if needed. Do this for both proto and
        // non-proto tombstones, even though proto tombstones do not support including the counter
        // of events dropped since rate limiting activated yet.
        DropboxRateLimiter.RateLimitResult rateLimitResult =
                sDropboxRateLimiter.shouldRateLimit(TAG_TOMBSTONE, processName);
        if (rateLimitResult.shouldRateLimit()) return;

        HashMap<String, Long> timestamps = readTimestamps();
        try {
            if (proto) {
@@ -328,7 +341,9 @@ public class BootReceiver extends BroadcastReceiver {
                    db.addFile(TAG_TOMBSTONE_PROTO, tombstone, 0);
                }
            } else {
                final String headers = getBootHeadersToLogAndUpdate();
                // Add the header indicating how many events have been dropped due to rate limiting.
                final String headers = getBootHeadersToLogAndUpdate()
                        + rateLimitResult.createHeader();
                addFileToDropBox(db, timestamps, headers, tombstone.getPath(), LOG_SIZE,
                                 TAG_TOMBSTONE);
            }
+1 −2
Original line number Diff line number Diff line
@@ -8819,8 +8819,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                        millisSinceOldestPendingRead).append("\n");
            }
        }
        sb.append("Dropped-Count: ").append(
                rateLimitResult.droppedCountSinceRateLimitActivated()).append("\n");
        sb.append(rateLimitResult.createHeader());
        sb.append("\n");
        // Do the rest in a worker thread to avoid blocking the caller on I/O
+7 −2
Original line number Diff line number Diff line
@@ -111,8 +111,8 @@ public class DropboxRateLimiter {

    /** Holds information on whether we should rate limit and how many events have been dropped. */
    public class RateLimitResult {
        boolean mShouldRateLimit;
        int mDroppedCountSinceRateLimitActivated;
        final boolean mShouldRateLimit;
        final int mDroppedCountSinceRateLimitActivated;

        public RateLimitResult(boolean shouldRateLimit, int droppedCountSinceRateLimitActivated) {
            mShouldRateLimit = shouldRateLimit;
@@ -128,6 +128,11 @@ public class DropboxRateLimiter {
        public int droppedCountSinceRateLimitActivated() {
            return mDroppedCountSinceRateLimitActivated;
        }

        /** Returns a header indicating the number of dropped events. */
        public String createHeader() {
            return "Dropped-Count: " + mDroppedCountSinceRateLimitActivated + "\n";
        }
    }

    private class ErrorRecord {
+28 −17
Original line number Diff line number Diff line
@@ -113,19 +113,22 @@ public final class NativeTombstoneManager {
            return;
        }

        if (filename.endsWith(".pb")) {
            handleProtoTombstone(path);
            BootReceiver.addTombstoneToDropBox(mContext, path, true);
        } else {
            BootReceiver.addTombstoneToDropBox(mContext, path, false);
        String processName = "UNKNOWN";
        final boolean isProtoFile = filename.endsWith(".pb");
        File protoPath = isProtoFile ? path : new File(path.getAbsolutePath() + ".pb");

        Optional<TombstoneFile> parsedTombstone = handleProtoTombstone(protoPath, isProtoFile);
        if (parsedTombstone.isPresent()) {
            processName = parsedTombstone.get().getProcessName();
        }
        BootReceiver.addTombstoneToDropBox(mContext, path, isProtoFile, processName);
    }

    private void handleProtoTombstone(File path) {
    private Optional<TombstoneFile> handleProtoTombstone(File path, boolean addToList) {
        final String filename = path.getName();
        if (!filename.endsWith(".pb")) {
            Slog.w(TAG, "unexpected tombstone name: " + path);
            return;
            return Optional.empty();
        }

        final String suffix = filename.substring("tombstone_".length());
@@ -136,11 +139,11 @@ public final class NativeTombstoneManager {
            number = Integer.parseInt(numberStr);
            if (number < 0 || number > 99) {
                Slog.w(TAG, "unexpected tombstone name: " + path);
                return;
                return Optional.empty();
            }
        } catch (NumberFormatException ex) {
            Slog.w(TAG, "unexpected tombstone name: " + path);
            return;
            return Optional.empty();
        }

        ParcelFileDescriptor pfd;
@@ -148,15 +151,16 @@ public final class NativeTombstoneManager {
            pfd = ParcelFileDescriptor.open(path, MODE_READ_WRITE);
        } catch (FileNotFoundException ex) {
            Slog.w(TAG, "failed to open " + path, ex);
            return;
            return Optional.empty();
        }

        final Optional<TombstoneFile> parsedTombstone = TombstoneFile.parse(pfd);
        if (!parsedTombstone.isPresent()) {
            IoUtils.closeQuietly(pfd);
            return;
            return Optional.empty();
        }

        if (addToList) {
            synchronized (mLock) {
                TombstoneFile previous = mTombstones.get(number);
                if (previous != null) {
@@ -167,6 +171,9 @@ public final class NativeTombstoneManager {
            }
        }

        return parsedTombstone;
    }

    /**
     * Remove native tombstones matching a user and/or app.
     *
@@ -363,6 +370,10 @@ public final class NativeTombstoneManager {
            return true;
        }

        public String getProcessName() {
            return mProcessName;
        }

        public void dispose() {
            IoUtils.closeQuietly(mPfd);
        }