OSDN Git Service

dumpstate: Add blocked process wait-channel info to bugreport
authorSan Mehat <san@google.com>
Tue, 27 Apr 2010 17:53:35 +0000 (10:53 -0700)
committerSan Mehat <san@google.com>
Tue, 27 Apr 2010 17:53:35 +0000 (10:53 -0700)
Fix for http://b/2630027

Change-Id: I3606d8bf95c58df2b290dbd13f48538d82f16088
Signed-off-by: San Mehat <san@google.com>
cmds/dumpstate/dumpstate.c
cmds/dumpstate/dumpstate.h
cmds/dumpstate/utils.c

index e8b5eaf..082e704 100644 (file)
@@ -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"
index 6d48a85..682eafd 100644 (file)
@@ -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_ */
index c21dace..c7a78cc 100644 (file)
 
 #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) {