diff options
author | 2010-04-27 10:53:35 -0700 | |
---|---|---|
committer | 2010-04-27 10:53:35 -0700 | |
commit | 57fff78a70c82ca09beb91c4f92d97b6f0b897e4 (patch) | |
tree | 2ee1dffe8135c478ff6bd1f60c8539eacff1bf01 | |
parent | 2e4b98dcd88f14fdb35e46236ec916493c570f28 (diff) |
dumpstate: Add blocked process wait-channel info to bugreport
Fix for http://b/2630027
Change-Id: I3606d8bf95c58df2b290dbd13f48538d82f16088
Signed-off-by: San Mehat <san@google.com>
-rw-r--r-- | cmds/dumpstate/dumpstate.c | 3 | ||||
-rw-r--r-- | cmds/dumpstate/dumpstate.h | 6 | ||||
-rw-r--r-- | cmds/dumpstate/utils.c | 58 |
3 files changed, 66 insertions, 1 deletions
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index e8b5eaff9052..082e704d6f77 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -138,6 +138,8 @@ static void dumpstate() { dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console"); dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads"); + for_each_pid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS"); + printf("------ BACKLIGHTS ------\n"); printf("LCD brightness="); dump_file(NULL, "/sys/class/leds/lcd-backlight/brightness"); @@ -161,7 +163,6 @@ static void dumpstate() { run_command("DUMPSYS", 60, "dumpsys", NULL); } - static void usage() { fprintf(stderr, "usage: dumpstate [-d] [-o file] [-s] [-z]\n" " -d: append date to filename (requires -o)\n" diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h index 6d48a859e15f..682eafdbab67 100644 --- a/cmds/dumpstate/dumpstate.h +++ b/cmds/dumpstate/dumpstate.h @@ -38,4 +38,10 @@ pid_t redirect_to_file(FILE *redirect, char *path, int gzip_level); /* dump Dalvik stack traces, return the trace file location (NULL if none) */ const char *dump_vm_traces(); +/* for each process in the system, run the specified function */ +void for_each_pid(void (*func)(int, const char *), const char *header); + +/* Displays a blocked processes in-kernel wait channel */ +void show_wchan(int pid, const char *name); + #endif /* _DUMPSTATE_H_ */ diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c index c21dace7c8c3..c7a78ccecef8 100644 --- a/cmds/dumpstate/utils.c +++ b/cmds/dumpstate/utils.c @@ -37,6 +37,64 @@ #include "dumpstate.h" +void for_each_pid(void (*func)(int, const char *), const char *header) { + DIR *d; + struct dirent *de; + + if (!(d = opendir("/proc"))) { + printf("Failed to open /proc (%s)\n", strerror(errno)); + return; + } + + printf("\n------ %s ------\n", header); + while ((de = readdir(d))) { + int pid; + int fd; + char cmdpath[255]; + char cmdline[255]; + + if (!(pid = atoi(de->d_name))) { + continue; + } + + sprintf(cmdpath,"/proc/%d/cmdline", pid); + memset(cmdline, 0, sizeof(cmdline)); + if ((fd = open(cmdpath, O_RDONLY)) < 0) { + strcpy(cmdline, "N/A"); + } else { + read(fd, cmdline, sizeof(cmdline)); + close(fd); + } + func(pid, cmdline); + } + + closedir(d); +} + +void show_wchan(int pid, const char *name) { + char path[255]; + char buffer[255]; + int fd; + + memset(buffer, 0, sizeof(buffer)); + + sprintf(path, "/proc/%d/wchan", pid); + if ((fd = open(path, O_RDONLY)) < 0) { + printf("Failed to open '%s' (%s)\n", path, strerror(errno)); + return; + } + + if (read(fd, buffer, sizeof(buffer)) < 0) { + printf("Failed to read '%s' (%s)\n", path, strerror(errno)); + goto out_close; + } + + printf("%-7d %-32s %s\n", pid, name, buffer); + +out_close: + close(fd); + return; +} /* prints the contents of a file */ int dump_file(const char *title, const char* path) { |