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

Commit 7dc7f322 authored by Christopher Ferris's avatar Christopher Ferris
Browse files

Add dumping of tombstones to dumpstate.

Dump only those tombstones modified within the last half an hour.

Change-Id: I8ce836b2e19eba7a9c0c31a4f312f9a382526da7
parent 2cbba477
Loading
Loading
Loading
Loading
+53 −6
Original line number Diff line number Diff line
@@ -20,13 +20,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/capability.h>
#include <sys/prctl.h>

#include <cutils/properties.h>

@@ -45,6 +45,36 @@ static char screenshot_path[PATH_MAX] = "";

#define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"

#define TOMBSTONE_DIR "/data/tombstones"
#define TOMBSTONE_FILE_PREFIX TOMBSTONE_DIR "/tombstone_"
/* Can accomodate a tombstone number up to 9999. */
#define TOMBSTONE_MAX_LEN (sizeof(TOMBSTONE_FILE_PREFIX) + 4)
#define NUM_TOMBSTONES  10

typedef struct {
  char name[TOMBSTONE_MAX_LEN];
  int fd;
} tombstone_data_t;

static tombstone_data_t tombstone_data[NUM_TOMBSTONES];

/* Get the fds of any tombstone that was modified in the last half an hour. */
static void get_tombstone_fds(tombstone_data_t data[NUM_TOMBSTONES]) {
    time_t thirty_minutes_ago = time(NULL) - 60*30;
    for (size_t i = 0; i < NUM_TOMBSTONES; i++) {
        snprintf(data[i].name, sizeof(data[i].name), "%s%02zu", TOMBSTONE_FILE_PREFIX, i);
        int fd = open(data[i].name, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
        struct stat st;
        if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) &&
                (time_t) st.st_mtime >= thirty_minutes_ago) {
            data[i].fd = fd;
        } else {
            close(fd);
            data[i].fd = -1;
        }
    }
}

/* dumps the current system state to stdout */
static void dumpstate() {
    time_t now = time(NULL);
@@ -119,7 +149,6 @@ static void dumpstate() {
    run_command("EVENT LOG", 20, "logcat", "-b", "events", "-v", "threadtime", "-d", "*:v", NULL);
    run_command("RADIO LOG", 20, "logcat", "-b", "radio", "-v", "threadtime", "-d", "*:v", NULL);


    /* show the traces we collected in main(), if that was done */
    if (dump_traces_path != NULL) {
        dump_file("VM TRACES JUST NOW", dump_traces_path);
@@ -131,10 +160,13 @@ static void dumpstate() {
    property_get("dalvik.vm.stack-trace-file", anr_traces_path, "");
    if (!anr_traces_path[0]) {
        printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
    } else if (stat(anr_traces_path, &st)) {
    } else {
      int fd = open(anr_traces_path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
      if (fd < 0) {
          printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno));
      } else {
        dump_file("VM TRACES AT LAST ANR", anr_traces_path);
          dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_path, fd);
      }
    }

    /* slow traces for slow operations */
@@ -155,6 +187,18 @@ static void dumpstate() {
        }
    }

    int dumped = 0;
    for (size_t i = 0; i < NUM_TOMBSTONES; i++) {
        if (tombstone_data[i].fd != -1) {
            dumped = 1;
            dump_file_from_fd("TOMBSTONE", tombstone_data[i].name, tombstone_data[i].fd);
            tombstone_data[i].fd = -1;
        }
    }
    if (!dumped) {
        printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR);
    }

    dump_file("NETWORK DEV INFO", "/proc/net/dev");
    dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all");
    dump_file("QTAGUID NETWORK INTERFACES INFO (xt)", "/proc/net/xt_qtaguid/iface_stat_fmt");
@@ -411,6 +455,9 @@ int main(int argc, char *argv[]) {
        return -1;
    }

    /* Get the tombstone fds here while we are running as root. */
    get_tombstone_fds(tombstone_data);

    /* switch to non-root user and group */
    gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW,
            AID_MOUNT, AID_INET, AID_NET_BW_STATS };
+5 −2
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ typedef void (for_each_userid_func)(int);
/* prints the contents of a file */
int dump_file(const char *title, const char *path);

/* prints the contents of the fd */
int dump_file_from_fd(const char *title, const char *path, int fd);

/* forks a command and waits for it to finish -- terminate args with NULL */
int run_command(const char *title, int timeout_seconds, const char *command, ...);

+7 −3
Original line number Diff line number Diff line
@@ -250,7 +250,6 @@ void do_showmap(int pid, const char *name) {

/* prints the contents of a file */
int dump_file(const char *title, const char *path) {
    char buffer[32768];
    int fd = open(path, O_RDONLY);
    if (fd < 0) {
        int err = errno;
@@ -259,6 +258,11 @@ int dump_file(const char *title, const char* path) {
        if (title) printf("\n");
        return -1;
    }
    return dump_file_from_fd(title, path, fd);
}

int dump_file_from_fd(const char *title, const char *path, int fd) {
    char buffer[32768];

    if (title) printf("------ %s (%s", title, path);

@@ -282,8 +286,8 @@ int dump_file(const char *title, const char* path) {
        }
        if (ret <= 0) break;
    }

    close(fd);

    if (!newline) printf("\n");
    if (title) printf("\n");
    return 0;