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

Commit 42471dd5 authored by Dan Egnor's avatar Dan Egnor
Browse files

Simplify & update ANR logging; report ANR data into the dropbox.

Eliminate the per-process 200ms timeout during ANR thread-dumping.
Dump all the threads at once, then wait for the file to stabilize.
Seems to work great and is much, much, much faster.

Don't dump stack traces to traces.txt on app crashes (it isn't very
useful and mostly just clutters up the file).

Tweak the formatting of the dropbox dumpsys a bit, for readability,
and avoid running out of memory when dumping large log files.

Report build & kernel version with kernel log dropbox entries.
parent c408d5c2
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -53,6 +53,15 @@ public class Build {
    /** The end-user-visible name for the end product. */
    public static final String MODEL = getString("ro.product.model");

    /** @pending The system bootloader version number. */
    public static final String BOOTLOADER = getString("ro.bootloader");

    /** @pending The radio firmware version number. */
    public static final String RADIO = getString("gsm.version.baseband");

    /** @pending The device serial number. */
    public static final String SERIAL = getString("ro.serialno");

    /** Various version strings. */
    public static class VERSION {
        /**
+5 −3
Original line number Diff line number Diff line
@@ -153,14 +153,16 @@ public class FileUtils
    public static String readTextFile(File file, int max, String ellipsis) throws IOException {
        InputStream input = new FileInputStream(file);
        try {
            if (max > 0) {  // "head" mode: read the first N bytes
            long size = file.length();
            if (max > 0 || (size > 0 && max == 0)) {  // "head" mode: read the first N bytes
                if (size > 0 && (max == 0 || size < max)) max = (int) size;
                byte[] data = new byte[max + 1];
                int length = input.read(data);
                if (length <= 0) return "";
                if (length <= max) return new String(data, 0, length);
                if (ellipsis == null) return new String(data, 0, max);
                return new String(data, 0, max) + ellipsis;
            } else if (max < 0) {  // "tail" mode: read it all, keep the last N
            } else if (max < 0) {  // "tail" mode: keep the last N
                int len;
                boolean rolled = false;
                byte[] last = null, data = null;
@@ -180,7 +182,7 @@ public class FileUtils
                }
                if (ellipsis == null || !rolled) return new String(last);
                return ellipsis + new String(last);
            } else {  // "cat" mode: read it all
            } else {  // "cat" mode: size unknown, read it all in streaming fashion
                ByteArrayOutputStream contents = new ByteArrayOutputStream();
                int len;
                byte[] data = new byte[1024];
+7 −1
Original line number Diff line number Diff line
@@ -2942,6 +2942,12 @@ public final class Settings {
         */
        public static final String MOUNT_UMS_NOTIFY_ENABLED = "mount_ums_notify_enabled";

        /**
         * If nonzero, ANRs in invisible background processes bring up a dialog.
         * Otherwise, the process will be silently killed.
         * @hide
         */
        public static final String ANR_SHOW_BACKGROUND = "anr_show_background";

        /**
         * @hide
+21 −6
Original line number Diff line number Diff line
@@ -38,6 +38,10 @@ import java.io.IOException;
public class BootReceiver extends BroadcastReceiver {
    private static final String TAG = "BootReceiver";

    // Negative meaning capture the *last* 64K of the file
    // (passed to FileUtils.readTextFile)
    private static final int LOG_SIZE = -65536;

    @Override
    public void onReceive(Context context, Intent intent) {
        try {
@@ -67,16 +71,20 @@ public class BootReceiver extends BroadcastReceiver {
    private void logBootEvents(Context context) throws IOException {
        DropBoxManager db = (DropBoxManager) context.getSystemService(Context.DROPBOX_SERVICE);

        String build =
                "Build: " + Build.FINGERPRINT + "\nKernel: " +
                FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n");
        StringBuilder props = new StringBuilder();
        props.append("Build: ").append(Build.FINGERPRINT).append("\n");
        props.append("Hardware: ").append(Build.BOARD).append("\n");
        props.append("Bootloader: ").append(Build.BOOTLOADER).append("\n");
        props.append("Radio: ").append(Build.RADIO).append("\n");
        props.append("Kernel: ");
        props.append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"));

        if (SystemProperties.getLong("ro.runtime.firstboot", 0) == 0) {
            String now = Long.toString(System.currentTimeMillis());
            SystemProperties.set("ro.runtime.firstboot", now);
            if (db != null) db.addText("SYSTEM_BOOT", build);
            if (db != null) db.addText("SYSTEM_BOOT", props.toString());
        } else {
            if (db != null) db.addText("SYSTEM_RESTART", build);
            if (db != null) db.addText("SYSTEM_RESTART", props.toString());
            return;  // Subsequent boot, don't log kernel boot log
        }

@@ -98,6 +106,13 @@ public class BootReceiver extends BroadcastReceiver {
        String setting = "logfile:" + filename;
        long lastTime = Settings.Secure.getLong(cr, setting, 0);
        if (lastTime == fileTime) return;  // Already logged this particular file
        db.addFile(tag, file, DropBoxManager.IS_TEXT);
        Settings.Secure.putLong(cr, setting, fileTime);

        StringBuilder report = new StringBuilder();
        report.append("Build: ").append(Build.FINGERPRINT).append("\n");
        report.append("Kernel: ");
        report.append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"));
        report.append(FileUtils.readTextFile(new File(filename), LOG_SIZE, "[[TRUNCATED]]\n"));
        db.addText(tag, report.toString());
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -305,6 +305,7 @@ public final class DropBoxManagerService extends IDropBoxManagerService.Stub {
            if (!match) continue;

            numFound++;
            if (doPrint) out.append("========================================\n");
            out.append(date).append(" ").append(entry.tag == null ? "(no tag)" : entry.tag);
            if (entry.file == null) {
                out.append(" (no file)\n");
@@ -339,6 +340,12 @@ public final class DropBoxManagerService extends IDropBoxManagerService.Stub {
                            if (n <= 0) break;
                            out.append(buf, 0, n);
                            newline = (buf[n - 1] == '\n');

                            // Flush periodically when printing to avoid out-of-memory.
                            if (out.length() > 65536) {
                                pw.write(out.toString());
                                out.setLength(0);
                            }
                        }
                        if (!newline) out.append("\n");
                    } else {
Loading