From 8f00ed038f1de6fa0bbc73588f849b969be1d841 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Wed, 7 Dec 2016 17:42:44 -0800 Subject: Fixed buffering issues. - Replace all printf(...) and puts(...) calls to dprintf(STDOUT_FILENO). - Replace all fflush(stdout) calls to fsync(STDOUT_FILENO). - Added duration reporters on for_each functions. Change-Id: If14b4d14ffc23bfead2ca8ad23b7b3027de01156 Fixes: 33128765 Test: manual verification Test: dumpstate_test passes --- cmds/dumpstate/utils.cpp | 127 ++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 61 deletions(-) (limited to 'cmds/dumpstate/utils.cpp') diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp index 01a60da566..8e6ccfc5d9 100644 --- a/cmds/dumpstate/utils.cpp +++ b/cmds/dumpstate/utils.cpp @@ -97,9 +97,9 @@ DurationReporter::~DurationReporter() { MYLOGD("Duration of '%s': %.3fs\n", title_.c_str(), (float)elapsed / NANOS_PER_SEC); } else { // Use "Yoda grammar" to make it easier to grep|sort sections. - printf("------ %.3fs was the duration of '%s' ------\n", (float)elapsed / NANOS_PER_SEC, - title_.c_str()); - fflush(stdout); + dprintf(STDOUT_FILENO, "------ %.3fs was the duration of '%s' ------\n", + (float)elapsed / NANOS_PER_SEC, title_.c_str()); + fsync(STDOUT_FILENO); } } } @@ -227,16 +227,19 @@ void Dumpstate::SetProgress(std::unique_ptr progress) { } void for_each_userid(void (*func)(int), const char *header) { + std::string title = header == nullptr ? "for_each_userid" : android::base::StringPrintf( + "for_each_userid(%s)", header); + DurationReporter duration_reporter(title); if (PropertiesHelper::IsDryRun()) return; DIR *d; struct dirent *de; - if (header) printf("\n------ %s ------\n", header); + if (header) dprintf(STDOUT_FILENO, "\n------ %s ------\n", header); func(0); if (!(d = opendir("/data/system/users"))) { - printf("Failed to open /data/system/users (%s)\n", strerror(errno)); + dprintf(STDOUT_FILENO, "Failed to open /data/system/users (%s)\n", strerror(errno)); return; } @@ -256,11 +259,11 @@ static void __for_each_pid(void (*helper)(int, const char *, void *), const char struct dirent *de; if (!(d = opendir("/proc"))) { - printf("Failed to open /proc (%s)\n", strerror(errno)); + dprintf(STDOUT_FILENO, "Failed to open /proc (%s)\n", strerror(errno)); return; } - if (header) printf("\n------ %s ------\n", header); + if (header) dprintf(STDOUT_FILENO, "\n------ %s ------\n", header); while ((de = readdir(d))) { int pid; int fd; @@ -310,6 +313,9 @@ 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) { + std::string title = header == nullptr ? "for_each_pid" + : android::base::StringPrintf("for_each_pid(%s)", header); + DurationReporter duration_reporter(title); if (PropertiesHelper::IsDryRun()) return; __for_each_pid(for_each_pid_helper, header, (void *) func); @@ -324,7 +330,7 @@ static void for_each_tid_helper(int pid, const char *cmdline, void *arg) { snprintf(taskpath, sizeof(taskpath), "/proc/%d/task", pid); if (!(d = opendir(taskpath))) { - printf("Failed to open %s (%s)\n", taskpath, strerror(errno)); + dprintf(STDOUT_FILENO, "Failed to open %s (%s)\n", taskpath, strerror(errno)); return; } @@ -364,6 +370,9 @@ 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) { + std::string title = header == nullptr ? "for_each_tid" + : android::base::StringPrintf("for_each_tid(%s)", header); + DurationReporter duration_reporter(title); if (PropertiesHelper::IsDryRun()) return; __for_each_pid(for_each_tid_helper, header, (void *) func); @@ -381,7 +390,7 @@ void show_wchan(int pid, int tid, const char *name) { snprintf(path, sizeof(path), "/proc/%d/wchan", tid); if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) { - printf("Failed to open '%s' (%s)\n", path, strerror(errno)); + dprintf(STDOUT_FILENO, "Failed to open '%s' (%s)\n", path, strerror(errno)); return; } @@ -390,14 +399,14 @@ void show_wchan(int pid, int tid, const char *name) { close(fd); if (ret < 0) { - printf("Failed to read '%s' (%s)\n", path, strerror(save_errno)); + dprintf(STDOUT_FILENO, "Failed to read '%s' (%s)\n", path, strerror(save_errno)); return; } snprintf(name_buffer, sizeof(name_buffer), "%*s%s", pid == tid ? 0 : 3, "", name); - printf("%-7d %-32s %s\n", tid, name_buffer, buffer); + dprintf(STDOUT_FILENO, "%-7d %-32s %s\n", tid, name_buffer, buffer); return; } @@ -447,7 +456,7 @@ void show_showtime(int pid, const char *name) { snprintf(path, sizeof(path), "/proc/%d/stat", pid); if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) { - printf("Failed to open '%s' (%s)\n", path, strerror(errno)); + dprintf(STDOUT_FILENO, "Failed to open '%s' (%s)\n", path, strerror(errno)); return; } @@ -456,7 +465,7 @@ void show_showtime(int pid, const char *name) { close(fd); if (ret < 0) { - printf("Failed to read '%s' (%s)\n", path, strerror(save_errno)); + dprintf(STDOUT_FILENO, "Failed to read '%s' (%s)\n", path, strerror(save_errno)); return; } @@ -495,7 +504,7 @@ void show_showtime(int pid, const char *name) { if (iotime) { snprdec(buffer, sizeof(buffer), 79, permille); } - puts(buffer); // adds a trailing newline + dprintf(STDOUT_FILENO, "%s\n", buffer); return; } @@ -503,29 +512,29 @@ void show_showtime(int pid, const char *name) { void do_dmesg() { const char *title = "KERNEL LOG (dmesg)"; DurationReporter duration_reporter(title); - printf("------ %s ------\n", title); + dprintf(STDOUT_FILENO, "------ %s ------\n", title); if (PropertiesHelper::IsDryRun()) return; /* Get size of kernel buffer */ int size = klogctl(KLOG_SIZE_BUFFER, NULL, 0); if (size <= 0) { - printf("Unexpected klogctl return value: %d\n\n", size); + dprintf(STDOUT_FILENO, "Unexpected klogctl return value: %d\n\n", size); return; } char *buf = (char *) malloc(size + 1); if (buf == NULL) { - printf("memory allocation failed\n\n"); + dprintf(STDOUT_FILENO, "memory allocation failed\n\n"); return; } int retval = klogctl(KLOG_READ_ALL, buf, size); if (retval < 0) { - printf("klogctl failure\n\n"); + dprintf(STDOUT_FILENO, "klogctl failure\n\n"); free(buf); return; } buf[retval] = '\0'; - printf("%s\n\n", buf); + dprintf(STDOUT_FILENO, "%s\n\n", buf); free(buf); return; } @@ -546,7 +555,7 @@ int Dumpstate::DumpFile(const std::string& title, const std::string& path) { UpdateProgress(WEIGHT_FILE); - fflush(stdout); + fsync(STDOUT_FILENO); return status; } @@ -588,7 +597,7 @@ int dump_files(const std::string& title, const char* dir, bool (*skip)(const cha int fd, retval = 0; if (!title.empty()) { - printf("------ %s (%s) ------\n", title.c_str(), dir); + dprintf(STDOUT_FILENO, "------ %s (%s) ------\n", title.c_str(), dir); } if (PropertiesHelper::IsDryRun()) return 0; @@ -630,14 +639,14 @@ int dump_files(const std::string& title, const char* dir, bool (*skip)(const cha fd = TEMP_FAILURE_RETRY(open(newpath, O_RDONLY | O_NONBLOCK | O_CLOEXEC)); if (fd < 0) { retval = fd; - printf("*** %s: %s\n", newpath, strerror(errno)); + dprintf(STDOUT_FILENO, "*** %s: %s\n", newpath, strerror(errno)); continue; } (*dump_from_fd)(NULL, newpath, fd); } closedir(dirp); if (!title.empty()) { - printf("\n"); + dprintf(STDOUT_FILENO, "\n"); } return retval; } @@ -651,11 +660,12 @@ int dump_file_from_fd(const char *title, const char *path, int fd) { int flags = fcntl(fd, F_GETFL); if (flags == -1) { - printf("*** %s: failed to get flags on fd %d: %s\n", path, fd, strerror(errno)); + dprintf(STDOUT_FILENO, "*** %s: failed to get flags on fd %d: %s\n", path, fd, + strerror(errno)); close(fd); return -1; } else if (!(flags & O_NONBLOCK)) { - printf("*** %s: fd must have O_NONBLOCK set.\n", path); + dprintf(STDOUT_FILENO, "*** %s: fd must have O_NONBLOCK set.\n", path); close(fd); return -1; } @@ -674,7 +684,7 @@ int Dumpstate::RunCommand(const std::string& title, const std::vector