Add option to #define _DUMPSTATE_DRY_RUN_ to skip the actual dumps.
Such option is useful when debugging dumpstate itself, since it will
finish much sooner and its output will be much smaller.
Change-Id: If821ed21715461bf82eea0b2be4b926239ad69da
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 7560416..814b1c2 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -770,11 +770,12 @@
/* 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");
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index f10ec46..f9f20d2 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -17,6 +17,18 @@
#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 @@
/* 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();
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 12f44ae..e6594ec 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -60,6 +60,7 @@
}
void for_each_userid(void (*func)(int), const char *header) {
+ ON_DRY_RUN_RETURN();
DIR *d;
struct dirent *de;
@@ -122,6 +123,7 @@
}
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 @@
}
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 @@
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 @@
/* 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 @@
if (title) {
printf("------ %s (%s) ------\n", title, dir);
}
+ ON_DRY_RUN_RETURN(0);
if (dir[strlen(dir) - 1] == '/') {
++slash;
@@ -384,6 +392,7 @@
* 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 @@
/* 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 @@
/* 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 @@
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 @@
/* 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 @@
/* 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 @@
}
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");