Loading cmds/dumpstate/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -16,4 +16,6 @@ LOCAL_STATIC_LIBRARIES := $(BOARD_LIB_DUMPSTATE) LOCAL_CFLAGS += -DBOARD_HAS_DUMPSTATE endif LOCAL_CFLAGS += -Wall -Wno-unused-parameter -std=gnu99 include $(BUILD_EXECUTABLE) cmds/dumpstate/dumpstate.c +2 −2 Original line number Diff line number Diff line Loading @@ -324,8 +324,8 @@ int main(int argc, char *argv[]) { fclose(oom_adj); } /* very first thing, collect VM traces from Dalvik (needs root) */ dump_traces_path = dump_vm_traces(); /* very first thing, collect stack traces from Dalvik and native processes (needs root) */ dump_traces_path = dump_traces(); int c; while ((c = getopt(argc, argv, "b:de:ho:svzp")) != -1) { Loading cmds/dumpstate/dumpstate.h +2 −2 Original line number Diff line number Diff line Loading @@ -38,8 +38,8 @@ void redirect_to_socket(FILE *redirect, const char *service); /* redirect output to a file, optionally gzipping; returns gzip pid */ 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(); /* dump Dalvik and native stack traces, return the trace file location (NULL if none) */ const char *dump_traces(); /* for each process in the system, run the specified function */ void for_each_pid(void (*func)(int, const char *), const char *header); Loading cmds/dumpstate/utils.c +76 −34 Original line number Diff line number Diff line Loading @@ -32,12 +32,21 @@ #include <time.h> #include <unistd.h> #include <cutils/debugger.h> #include <cutils/properties.h> #include <cutils/sockets.h> #include <private/android_filesystem_config.h> #include "dumpstate.h" /* list of native processes to include in the native dumps */ static const char* native_processes_to_dump[] = { "/system/bin/mediaserver", "/system/bin/sdcard", "/system/bin/surfaceflinger", NULL, }; void for_each_pid(void (*func)(int, const char *), const char *header) { DIR *d; struct dirent *de; Loading Loading @@ -352,8 +361,19 @@ pid_t redirect_to_file(FILE *redirect, char *path, int gzip_level) { return gzip_pid; } /* dump Dalvik stack traces, return the trace file location (NULL if none) */ const char *dump_vm_traces() { static bool should_dump_native_traces(const char* path) { for (const char** p = native_processes_to_dump; *p; p++) { if (!strcmp(*p, path)) { return true; } } return false; } /* dump Dalvik and native stack traces, return the trace file location (NULL if none) */ const char *dump_traces() { const char* result = NULL; char traces_path[PROPERTY_VALUE_MAX] = ""; property_get("dalvik.vm.stack-trace-file", traces_path, ""); if (!traces_path[0]) return NULL; Loading Loading @@ -394,26 +414,25 @@ const char *dump_vm_traces() { close(fd); return NULL; } close(fd); /* walk /proc and kill -QUIT all Dalvik processes */ DIR *proc = opendir("/proc"); if (proc == NULL) { fprintf(stderr, "/proc: %s\n", strerror(errno)); return NULL; goto error_close_fd; } /* use inotify to find when processes are done dumping */ int ifd = inotify_init(); if (ifd < 0) { fprintf(stderr, "inotify_init: %s\n", strerror(errno)); return NULL; goto error_close_fd; } int wfd = inotify_add_watch(ifd, traces_path, IN_CLOSE_WRITE); if (wfd < 0) { fprintf(stderr, "inotify_add_watch(%s): %s\n", traces_path, strerror(errno)); return NULL; goto error_close_ifd; } struct dirent *d; Loading @@ -422,18 +441,28 @@ const char *dump_vm_traces() { int pid = atoi(d->d_name); if (pid <= 0) continue; /* identify Dalvik: /proc/(pid)/exe = /system/bin/app_process */ char path[PATH_MAX], data[PATH_MAX]; char path[PATH_MAX]; char data[PATH_MAX]; snprintf(path, sizeof(path), "/proc/%d/exe", pid); size_t len = readlink(path, data, sizeof(data) - 1); if (len <= 0 || memcmp(data, "/system/bin/app_process", 23)) continue; ssize_t len = readlink(path, data, sizeof(data) - 1); if (len <= 0) { continue; } data[len] = '\0'; if (!strcmp(data, "/system/bin/app_process")) { /* skip zygote -- it won't dump its stack anyway */ snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); int fd = open(path, O_RDONLY); len = read(fd, data, sizeof(data) - 1); close(fd); if (len <= 0 || !memcmp(data, "zygote", 6)) continue; if (len <= 0) { continue; } data[len] = '\0'; if (!strcmp(data, "zygote")) { continue; } ++dalvik_found; if (kill(pid, SIGQUIT)) { Loading @@ -452,9 +481,16 @@ const char *dump_vm_traces() { struct inotify_event ie; read(ifd, &ie, sizeof(ie)); } } else if (should_dump_native_traces(data)) { /* dump native process if appropriate */ if (lseek(fd, 0, SEEK_END) < 0) { fprintf(stderr, "lseek: %s\n", strerror(errno)); } else { dump_backtrace_to_file(pid, fd); } } } close(ifd); if (dalvik_found == 0) { fprintf(stderr, "Warning: no Dalvik processes found to dump stacks\n"); } Loading @@ -464,12 +500,18 @@ const char *dump_vm_traces() { strlcat(dump_traces_path, ".bugreport", sizeof(dump_traces_path)); if (rename(traces_path, dump_traces_path)) { fprintf(stderr, "rename(%s, %s): %s\n", traces_path, dump_traces_path, strerror(errno)); return NULL; goto error_close_ifd; } result = dump_traces_path; /* replace the saved [ANR] traces.txt file */ rename(anr_traces_path, traces_path); return dump_traces_path; error_close_ifd: close(ifd); error_close_fd: close(fd); return result; } void play_sound(const char* path) { Loading Loading
cmds/dumpstate/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -16,4 +16,6 @@ LOCAL_STATIC_LIBRARIES := $(BOARD_LIB_DUMPSTATE) LOCAL_CFLAGS += -DBOARD_HAS_DUMPSTATE endif LOCAL_CFLAGS += -Wall -Wno-unused-parameter -std=gnu99 include $(BUILD_EXECUTABLE)
cmds/dumpstate/dumpstate.c +2 −2 Original line number Diff line number Diff line Loading @@ -324,8 +324,8 @@ int main(int argc, char *argv[]) { fclose(oom_adj); } /* very first thing, collect VM traces from Dalvik (needs root) */ dump_traces_path = dump_vm_traces(); /* very first thing, collect stack traces from Dalvik and native processes (needs root) */ dump_traces_path = dump_traces(); int c; while ((c = getopt(argc, argv, "b:de:ho:svzp")) != -1) { Loading
cmds/dumpstate/dumpstate.h +2 −2 Original line number Diff line number Diff line Loading @@ -38,8 +38,8 @@ void redirect_to_socket(FILE *redirect, const char *service); /* redirect output to a file, optionally gzipping; returns gzip pid */ 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(); /* dump Dalvik and native stack traces, return the trace file location (NULL if none) */ const char *dump_traces(); /* for each process in the system, run the specified function */ void for_each_pid(void (*func)(int, const char *), const char *header); Loading
cmds/dumpstate/utils.c +76 −34 Original line number Diff line number Diff line Loading @@ -32,12 +32,21 @@ #include <time.h> #include <unistd.h> #include <cutils/debugger.h> #include <cutils/properties.h> #include <cutils/sockets.h> #include <private/android_filesystem_config.h> #include "dumpstate.h" /* list of native processes to include in the native dumps */ static const char* native_processes_to_dump[] = { "/system/bin/mediaserver", "/system/bin/sdcard", "/system/bin/surfaceflinger", NULL, }; void for_each_pid(void (*func)(int, const char *), const char *header) { DIR *d; struct dirent *de; Loading Loading @@ -352,8 +361,19 @@ pid_t redirect_to_file(FILE *redirect, char *path, int gzip_level) { return gzip_pid; } /* dump Dalvik stack traces, return the trace file location (NULL if none) */ const char *dump_vm_traces() { static bool should_dump_native_traces(const char* path) { for (const char** p = native_processes_to_dump; *p; p++) { if (!strcmp(*p, path)) { return true; } } return false; } /* dump Dalvik and native stack traces, return the trace file location (NULL if none) */ const char *dump_traces() { const char* result = NULL; char traces_path[PROPERTY_VALUE_MAX] = ""; property_get("dalvik.vm.stack-trace-file", traces_path, ""); if (!traces_path[0]) return NULL; Loading Loading @@ -394,26 +414,25 @@ const char *dump_vm_traces() { close(fd); return NULL; } close(fd); /* walk /proc and kill -QUIT all Dalvik processes */ DIR *proc = opendir("/proc"); if (proc == NULL) { fprintf(stderr, "/proc: %s\n", strerror(errno)); return NULL; goto error_close_fd; } /* use inotify to find when processes are done dumping */ int ifd = inotify_init(); if (ifd < 0) { fprintf(stderr, "inotify_init: %s\n", strerror(errno)); return NULL; goto error_close_fd; } int wfd = inotify_add_watch(ifd, traces_path, IN_CLOSE_WRITE); if (wfd < 0) { fprintf(stderr, "inotify_add_watch(%s): %s\n", traces_path, strerror(errno)); return NULL; goto error_close_ifd; } struct dirent *d; Loading @@ -422,18 +441,28 @@ const char *dump_vm_traces() { int pid = atoi(d->d_name); if (pid <= 0) continue; /* identify Dalvik: /proc/(pid)/exe = /system/bin/app_process */ char path[PATH_MAX], data[PATH_MAX]; char path[PATH_MAX]; char data[PATH_MAX]; snprintf(path, sizeof(path), "/proc/%d/exe", pid); size_t len = readlink(path, data, sizeof(data) - 1); if (len <= 0 || memcmp(data, "/system/bin/app_process", 23)) continue; ssize_t len = readlink(path, data, sizeof(data) - 1); if (len <= 0) { continue; } data[len] = '\0'; if (!strcmp(data, "/system/bin/app_process")) { /* skip zygote -- it won't dump its stack anyway */ snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); int fd = open(path, O_RDONLY); len = read(fd, data, sizeof(data) - 1); close(fd); if (len <= 0 || !memcmp(data, "zygote", 6)) continue; if (len <= 0) { continue; } data[len] = '\0'; if (!strcmp(data, "zygote")) { continue; } ++dalvik_found; if (kill(pid, SIGQUIT)) { Loading @@ -452,9 +481,16 @@ const char *dump_vm_traces() { struct inotify_event ie; read(ifd, &ie, sizeof(ie)); } } else if (should_dump_native_traces(data)) { /* dump native process if appropriate */ if (lseek(fd, 0, SEEK_END) < 0) { fprintf(stderr, "lseek: %s\n", strerror(errno)); } else { dump_backtrace_to_file(pid, fd); } } } close(ifd); if (dalvik_found == 0) { fprintf(stderr, "Warning: no Dalvik processes found to dump stacks\n"); } Loading @@ -464,12 +500,18 @@ const char *dump_vm_traces() { strlcat(dump_traces_path, ".bugreport", sizeof(dump_traces_path)); if (rename(traces_path, dump_traces_path)) { fprintf(stderr, "rename(%s, %s): %s\n", traces_path, dump_traces_path, strerror(errno)); return NULL; goto error_close_ifd; } result = dump_traces_path; /* replace the saved [ANR] traces.txt file */ rename(anr_traces_path, traces_path); return dump_traces_path; error_close_ifd: close(ifd); error_close_fd: close(fd); return result; } void play_sound(const char* path) { Loading