summaryrefslogtreecommitdiffstats
path: root/cmds
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2014-07-22 16:08:19 -0700
committerChristopher Ferris <cferris@google.com>2014-07-23 19:18:07 -0700
commit7dc7f3221f26b771c266a26ec785eb74287922f1 (patch)
tree9fe39e5a72da651d45f2a430e21f1f7c60a95abe /cmds
parent2cbba477bea136698944ece498115dbddd7bb659 (diff)
downloadframeworks_native-7dc7f3221f26b771c266a26ec785eb74287922f1.zip
frameworks_native-7dc7f3221f26b771c266a26ec785eb74287922f1.tar.gz
frameworks_native-7dc7f3221f26b771c266a26ec785eb74287922f1.tar.bz2
Add dumping of tombstones to dumpstate.
Dump only those tombstones modified within the last half an hour. Change-Id: I8ce836b2e19eba7a9c0c31a4f312f9a382526da7
Diffstat (limited to 'cmds')
-rw-r--r--cmds/dumpstate/dumpstate.c59
-rw-r--r--cmds/dumpstate/dumpstate.h7
-rw-r--r--cmds/dumpstate/utils.c10
3 files changed, 65 insertions, 11 deletions
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index ff01da5..d2f99df 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -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)) {
- 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);
+ 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_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 };
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 111bda6..53bfff6 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -29,7 +29,10 @@ typedef void (for_each_tid_func)(int, int, const char *);
typedef void (for_each_userid_func)(int);
/* prints the contents of a file */
-int dump_file(const char *title, const char* path);
+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, ...);
@@ -71,7 +74,7 @@ void do_dump_settings(int userid);
void dump_route_tables();
/* Play a sound via Stagefright */
-void play_sound(const char* path);
+void play_sound(const char *path);
/* Implemented by libdumpstate_board to dump board-specific info */
void dumpstate_board();
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 7694adb..a6d9ef6 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -249,8 +249,7 @@ 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 dump_file(const char *title, const char *path) {
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;