Loading cmds/dumpstate/dumpstate.c +53 −6 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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); Loading Loading @@ -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); Loading @@ -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 */ Loading @@ -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"); Loading Loading @@ -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 }; Loading cmds/dumpstate/dumpstate.h +5 −2 Original line number Diff line number Diff line Loading @@ -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, ...); Loading cmds/dumpstate/utils.c +7 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading @@ -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; Loading Loading
cmds/dumpstate/dumpstate.c +53 −6 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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); Loading Loading @@ -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); Loading @@ -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 */ Loading @@ -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"); Loading Loading @@ -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 }; Loading
cmds/dumpstate/dumpstate.h +5 −2 Original line number Diff line number Diff line Loading @@ -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, ...); Loading
cmds/dumpstate/utils.c +7 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading @@ -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; Loading