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

Commit 8f4bd39c authored by Mohamad Mahmoud's avatar Mohamad Mahmoud
Browse files

Add Memory headers to ANR reports

Add some of the contents of the ANRing process's /proc/PID/status file as headers to the ANR

Test: Tested on device
Bug: 274115489
Change-Id: Iff19e2d3a5b28870e096e88a9f1099b2498d162b
parent 5c3c30d0
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@ import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
import static com.android.server.am.ActivityManagerService.MY_PID;
import static com.android.server.am.ProcessRecord.TAG;
import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;

import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AnrController;
import android.app.ApplicationErrorReport;
@@ -56,6 +58,7 @@ import com.android.internal.os.anr.AnrLatencyTracker;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.ResourcePressureUtil;
import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
import com.android.server.wm.WindowProcessController;

import java.io.File;
@@ -395,6 +398,8 @@ class ProcessErrorStateRecord {
                });
            }
        }
        // Build memory headers for the ANRing process.
        String memoryHeaders = buildMemoryHeadersFor(pid);

        // Get critical event log before logging the ANR so that it doesn't occur in the log.
        latencyTracker.criticalEventLogStarted();
@@ -495,7 +500,7 @@ class ProcessErrorStateRecord {
        File tracesFile = StackTracesDumpHelper.dumpStackTraces(firstPids,
                isSilentAnr ? null : processCpuTracker, isSilentAnr ? null : lastPids,
                nativePidsFuture, tracesFileException, firstPidEndOffset, annotation,
                criticalEventLog, auxiliaryTaskExecutor, latencyTracker);
                criticalEventLog, memoryHeaders, auxiliaryTaskExecutor, latencyTracker);

        if (isMonitorCpuUsage()) {
            // Wait for the first call to finish
@@ -709,6 +714,26 @@ class ProcessErrorStateRecord {
            resolver.getUserId()) != 0;
    }

    private @Nullable String buildMemoryHeadersFor(int pid) {
        if (pid <= 0) {
            Slog.i(TAG, "Memory header requested with invalid pid: " + pid);
            return null;
        }
        MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid);
        if (snapshot == null) {
            Slog.i(TAG, "Failed to get memory snapshot for pid:" + pid);
            return null;
        }

        StringBuilder memoryHeaders = new StringBuilder();
        memoryHeaders.append("RssHwmKb: ")
            .append(snapshot.rssHighWaterMarkInKilobytes)
            .append("\n");
        memoryHeaders.append("RssKb: ").append(snapshot.rssInKilobytes).append("\n");
        memoryHeaders.append("RssAnonKb: ").append(snapshot.anonRssInKilobytes).append("\n");
        memoryHeaders.append("VmSwapKb: ").append(snapshot.swapInKilobytes).append("\n");
        return memoryHeaders.toString();
    }
    /**
     * Unless configured otherwise, swallow ANRs in background processes & kill the process.
     * Non-private access is for tests only.
+8 −5
Original line number Diff line number Diff line
@@ -85,7 +85,8 @@ public class StackTracesDumpHelper {
            Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
            @NonNull Executor auxiliaryTaskExecutor, AnrLatencyTracker latencyTracker) {
        return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePidsFuture,
                logExceptionCreatingFile, null, null, null, auxiliaryTaskExecutor, latencyTracker);
                logExceptionCreatingFile, null, null, null, null, auxiliaryTaskExecutor,
                latencyTracker);
    }

    /**
@@ -99,7 +100,7 @@ public class StackTracesDumpHelper {
            AnrLatencyTracker latencyTracker) {
        return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePidsFuture,
                logExceptionCreatingFile, null, subject, criticalEventSection,
                auxiliaryTaskExecutor, latencyTracker);
                /* memoryHeaders= */ null, auxiliaryTaskExecutor, latencyTracker);
    }

    /**
@@ -110,7 +111,8 @@ public class StackTracesDumpHelper {
            ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
            Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
            AtomicLong firstPidEndOffset, String subject, String criticalEventSection,
            @NonNull Executor auxiliaryTaskExecutor, AnrLatencyTracker latencyTracker) {
            String memoryHeaders, @NonNull Executor auxiliaryTaskExecutor,
            AnrLatencyTracker latencyTracker) {
        try {

            if (latencyTracker != null) {
@@ -150,9 +152,10 @@ public class StackTracesDumpHelper {
                return null;
            }

            if (subject != null || criticalEventSection != null) {
            if (subject != null || criticalEventSection != null || memoryHeaders != null) {
                appendtoANRFile(tracesFile.getAbsolutePath(),
                        (subject != null ? "Subject: " + subject + "\n\n" : "")
                        (subject != null ? "Subject: " + subject + "\n" : "")
                        + (memoryHeaders != null ? memoryHeaders + "\n\n" : "")
                        + (criticalEventSection != null ? criticalEventSection : ""));
            }