OSDN Git Service

Add option to #define _DUMPSTATE_DRY_RUN_ to skip the actual dumps.
authorFelipe Leme <felipeal@google.com>
Wed, 11 Nov 2015 04:10:25 +0000 (20:10 -0800)
committerFelipe Leme <felipeal@google.com>
Wed, 11 Nov 2015 23:03:30 +0000 (15:03 -0800)
Such option is useful when debugging dumpstate itself, since it will
finish much sooner and its output will be much smaller.

Change-Id: If821ed21715461bf82eea0b2be4b926239ad69da

cmds/dumpstate/dumpstate.cpp
cmds/dumpstate/dumpstate.h
cmds/dumpstate/utils.cpp

index 7560416..814b1c2 100644 (file)
@@ -770,11 +770,12 @@ int main(int argc, char *argv[]) {
 
     /* tell activity manager we're done */
     if (do_broadcast && use_outfile && do_fb) {
-        run_command(NULL, 5, "/system/bin/am", "broadcast", "--user", "0",
+        const char *args[] = { "/system/bin/am", "broadcast", "--user", "0",
                 "-a", "android.intent.action.BUGREPORT_FINISHED",
                 "--es", "android.intent.extra.BUGREPORT", path,
                 "--es", "android.intent.extra.SCREENSHOT", screenshot_path,
-                "--receiver-permission", "android.permission.DUMP", NULL);
+                "--receiver-permission", "android.permission.DUMP", NULL };
+        run_command_always(NULL, 5, args);
     }
 
     ALOGI("done\n");
index f10ec46..f9f20d2 100644 (file)
 #ifndef _DUMPSTATE_H_
 #define _DUMPSTATE_H_
 
+/* When defined, skips the real dumps and just print the section headers.
+   Useful when debugging dumpstate itself. */
+//#define _DUMPSTATE_DRY_RUN_
+
+#ifdef _DUMPSTATE_DRY_RUN_
+#define ON_DRY_RUN_RETURN(X) return X
+#endif
+#ifndef _DUMPSTATE_DRY_RUN_
+#define ON_DRY_RUN_RETURN(X)
+#endif
+
+
 #include <time.h>
 #include <unistd.h>
 #include <stdbool.h>
@@ -52,6 +64,11 @@ int dump_files(const char *title, const char *dir,
 /* 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, ...);
 
+/* forks a command and waits for it to finish
+   first element of args is the command, and last must be NULL.
+   command is always ran, even when _DUMPSTATE_DRY_RUN_ is defined. */
+int run_command_always(const char *title, int timeout_seconds, const char *args[]);
+
 /* prints all the system properties */
 void print_properties();
 
index 12f44ae..e6594ec 100644 (file)
@@ -60,6 +60,7 @@ static uint64_t nanotime() {
 }
 
 void for_each_userid(void (*func)(int), const char *header) {
+    ON_DRY_RUN_RETURN();
     DIR *d;
     struct dirent *de;
 
@@ -122,6 +123,7 @@ static void for_each_pid_helper(int pid, const char *cmdline, void *arg) {
 }
 
 void for_each_pid(for_each_pid_func func, const char *header) {
+    ON_DRY_RUN_RETURN();
   __for_each_pid(for_each_pid_helper, header, (void *)func);
 }
 
@@ -174,10 +176,12 @@ static void for_each_tid_helper(int pid, const char *cmdline, void *arg) {
 }
 
 void for_each_tid(for_each_tid_func func, const char *header) {
+    ON_DRY_RUN_RETURN();
     __for_each_pid(for_each_tid_helper, header, (void *) func);
 }
 
 void show_wchan(int pid, int tid, const char *name) {
+    ON_DRY_RUN_RETURN();
     char path[255];
     char buffer[255];
     int fd;
@@ -208,6 +212,7 @@ out_close:
 
 void do_dmesg() {
     printf("------ KERNEL LOG (dmesg) ------\n");
+    ON_DRY_RUN_RETURN();
     /* Get size of kernel buffer */
     int size = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
     if (size <= 0) {
@@ -299,10 +304,12 @@ static int _dump_file_from_fd(const char *title, const char *path, int fd) {
 
 /* prints the contents of a file */
 int dump_file(const char *title, const char *path) {
+    if (title) printf("------ %s (%s) ------\n", title, path);
+    ON_DRY_RUN_RETURN(0);
+
     int fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
     if (fd < 0) {
         int err = errno;
-        if (title) printf("------ %s (%s) ------\n", title, path);
         printf("*** %s: %s\n", path, strerror(err));
         if (title) printf("\n");
         return -1;
@@ -328,6 +335,7 @@ int dump_files(const char *title, const char *dir,
     if (title) {
         printf("------ %s (%s) ------\n", title, dir);
     }
+    ON_DRY_RUN_RETURN(0);
 
     if (dir[strlen(dir) - 1] == '/') {
         ++slash;
@@ -384,6 +392,7 @@ int dump_files(const char *title, const char *dir,
  * stuck.
  */
 int dump_file_from_fd(const char *title, const char *path, int fd) {
+    ON_DRY_RUN_RETURN(0);
     int flags = fcntl(fd, F_GETFL);
     if (flags == -1) {
         printf("*** %s: failed to get flags on fd %d: %s\n", path, fd, strerror(errno));
@@ -442,6 +451,29 @@ bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) {
 /* forks a command and waits for it to finish */
 int run_command(const char *title, int timeout_seconds, const char *command, ...) {
     fflush(stdout);
+
+    const char *args[1024] = {command};
+    size_t arg;
+    va_list ap;
+    va_start(ap, command);
+    if (title) printf("------ %s (%s", title, command);
+    for (arg = 1; arg < sizeof(args) / sizeof(args[0]); ++arg) {
+        args[arg] = va_arg(ap, const char *);
+        if (args[arg] == NULL) break;
+        if (title) printf(" %s", args[arg]);
+    }
+    if (title) printf(") ------\n");
+    fflush(stdout);
+
+    ON_DRY_RUN_RETURN(0);
+
+    return run_command_always(title, timeout_seconds, args);
+}
+
+/* forks a command and waits for it to finish */
+int run_command_always(const char *title, int timeout_seconds, const char *args[]) {
+    const char *command = args[0];
+
     uint64_t start = nanotime();
     pid_t pid = fork();
 
@@ -453,8 +485,6 @@ int run_command(const char *title, int timeout_seconds, const char *command, ...
 
     /* handle child case */
     if (pid == 0) {
-        const char *args[1024] = {command};
-        size_t arg;
 
         /* make sure the child dies when dumpstate dies */
         prctl(PR_SET_PDEATHSIG, SIGKILL);
@@ -465,17 +495,6 @@ int run_command(const char *title, int timeout_seconds, const char *command, ...
         sigact.sa_handler = SIG_IGN;
         sigaction(SIGPIPE, &sigact, NULL);
 
-        va_list ap;
-        va_start(ap, command);
-        if (title) printf("------ %s (%s", title, command);
-        for (arg = 1; arg < sizeof(args) / sizeof(args[0]); ++arg) {
-            args[arg] = va_arg(ap, const char *);
-            if (args[arg] == NULL) break;
-            if (title) printf(" %s", args[arg]);
-        }
-        if (title) printf(") ------\n");
-        fflush(stdout);
-
         execvp(command, (char**) args);
         printf("*** exec(%s): %s\n", command, strerror(errno));
         fflush(stdout);
@@ -532,12 +551,13 @@ static int compare_prop(const void *a, const void *b) {
 
 /* prints all the system properties */
 void print_properties() {
+    printf("------ SYSTEM PROPERTIES ------\n");
+    ON_DRY_RUN_RETURN();
     size_t i;
     num_props = 0;
     property_list(print_prop, NULL);
     qsort(&props, num_props, sizeof(props[0]), compare_prop);
 
-    printf("------ SYSTEM PROPERTIES ------\n");
     for (i = 0; i < num_props; ++i) {
         fputs(props[i], stdout);
         free(props[i]);
@@ -611,6 +631,7 @@ static bool should_dump_native_traces(const char* path) {
 
 /* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
 const char *dump_traces() {
+    ON_DRY_RUN_RETURN(NULL);
     const char* result = NULL;
 
     char traces_path[PROPERTY_VALUE_MAX] = "";
@@ -764,6 +785,7 @@ error_close_fd:
 }
 
 void dump_route_tables() {
+    ON_DRY_RUN_RETURN();
     const char* const RT_TABLES_PATH = "/data/misc/net/rt_tables";
     dump_file("RT_TABLES", RT_TABLES_PATH);
     FILE* fp = fopen(RT_TABLES_PATH, "re");