summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Leme <felipeal@google.com>2015-11-10 20:10:25 -0800
committerMark Salyzyn <salyzyn@google.com>2016-02-09 07:37:12 -0800
commit68116161c74676ae6f8577e5154aca774657ec60 (patch)
tree57d94a4572938c4ac1570bd207697d25c9767266
parentfda23631b978bec793b67037dc2841a6a15531fb (diff)
downloadnative-68116161c74676ae6f8577e5154aca774657ec60.tar.gz
Add option to #define _DUMPSTATE_DRY_RUN_ to skip the actual dumps.
(cherry picked from commit 93d705b6d742e8f00167ff2384e35c2205a6f9da) Such option is useful when debugging dumpstate itself, since it will finish much sooner and its output will be much smaller. Change-Id: If821ed21715461bf82eea0b2be4b926239ad69da
-rw-r--r--cmds/dumpstate/dumpstate.cpp5
-rw-r--r--cmds/dumpstate/dumpstate.h17
-rw-r--r--cmds/dumpstate/utils.cpp52
3 files changed, 57 insertions, 17 deletions
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index db12bf2bc7..808d0c27df 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -885,11 +885,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");
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 3b6abc1d15..fb66065446 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 @@ 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();
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index c3e026230e..006b14b56a 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -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");