Proper stdout buffering using setvbuf().
Bug: 33128765
Test: manual verification
Test: dumpstate_test passes
Change-Id: Ie6dc9b7eb8416293c01963bf224aef92ad3a50c1
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index c4e5cfa..a0b0426 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -602,7 +602,7 @@
path += sizeof(mmcblk0) - 1;
}
- dprintf(STDOUT_FILENO, "%s: %s\n", path, buffer);
+ printf("%s: %s\n", path, buffer);
free(buffer);
if (fields[__STAT_IO_TICKS]) {
@@ -639,11 +639,10 @@
/ fields[__STAT_IO_TICKS];
if (!write_perf && !write_ios) {
- dprintf(STDOUT_FILENO, "%s: perf(ios) rd: %luKB/s(%lu/s) q: %u\n", path, read_perf,
- read_ios, queue);
+ printf("%s: perf(ios) rd: %luKB/s(%lu/s) q: %u\n", path, read_perf, read_ios, queue);
} else {
- dprintf(STDOUT_FILENO, "%s: perf(ios) rd: %luKB/s(%lu/s) wr: %luKB/s(%lu/s) q: %u\n",
- path, read_perf, read_ios, write_perf, write_ios, queue);
+ printf("%s: perf(ios) rd: %luKB/s(%lu/s) wr: %luKB/s(%lu/s) q: %u\n", path, read_perf,
+ read_ios, write_perf, write_ios, queue);
}
/* bugreport timeout factor adjustment */
@@ -673,27 +672,25 @@
network = android::base::GetProperty("gsm.operator.alpha", "(unknown)");
strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now_));
- dprintf(STDOUT_FILENO, "========================================================\n");
- dprintf(STDOUT_FILENO, "== dumpstate: %s\n", date);
- dprintf(STDOUT_FILENO, "========================================================\n");
+ printf("========================================================\n");
+ printf("== dumpstate: %s\n", date);
+ printf("========================================================\n");
- dprintf(STDOUT_FILENO, "\n");
- dprintf(STDOUT_FILENO, "Build: %s\n", build.c_str());
+ printf("\n");
+ printf("Build: %s\n", build.c_str());
// NOTE: fingerprint entry format is important for other tools.
- dprintf(STDOUT_FILENO, "Build fingerprint: '%s'\n", fingerprint.c_str());
- dprintf(STDOUT_FILENO, "Bootloader: %s\n", bootloader.c_str());
- dprintf(STDOUT_FILENO, "Radio: %s\n", radio.c_str());
- dprintf(STDOUT_FILENO, "Network: %s\n", network.c_str());
+ printf("Build fingerprint: '%s'\n", fingerprint.c_str());
+ printf("Bootloader: %s\n", bootloader.c_str());
+ printf("Radio: %s\n", radio.c_str());
+ printf("Network: %s\n", network.c_str());
- dprintf(STDOUT_FILENO, "Kernel: ");
- fsync(STDOUT_FILENO);
+ printf("Kernel: ");
DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
- dprintf(STDOUT_FILENO, "Command line: %s\n", strtok(cmdline_buf, "\n"));
- dprintf(STDOUT_FILENO, "Bugreport format version: %s\n", version_.c_str());
- dprintf(STDOUT_FILENO, "Dumpstate info: id=%d pid=%d dry_run=%d args=%s extra_options=%s\n",
- id_, pid_, PropertiesHelper::IsDryRun(), args_.c_str(), extra_options_.c_str());
- dprintf(STDOUT_FILENO, "\n");
- fsync(STDOUT_FILENO);
+ printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
+ printf("Bugreport format version: %s\n", version_.c_str());
+ printf("Dumpstate info: id=%d pid=%d dry_run=%d args=%s extra_options=%s\n", id_, pid_,
+ PropertiesHelper::IsDryRun(), args_.c_str(), extra_options_.c_str());
+ printf("\n");
}
// List of file extensions that can cause a zip file attachment to be rejected by some email
@@ -857,13 +854,13 @@
dump_traces_dir.c_str(), anr_traces_dir.c_str(), already_dumped);
if (anr_traces_path.empty()) {
- dprintf(STDOUT_FILENO, "*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
+ printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
} else {
int fd = TEMP_FAILURE_RETRY(
open(anr_traces_path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
if (fd < 0) {
- dprintf(STDOUT_FILENO, "*** NO ANR VM TRACES FILE (%s): %s\n\n",
- anr_traces_path.c_str(), strerror(errno));
+ printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path.c_str(),
+ strerror(errno));
} else {
if (add_to_zip) {
if (!already_dumped) {
@@ -1003,7 +1000,7 @@
}
}
if (!dumped) {
- dprintf(STDOUT_FILENO, "*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR);
+ printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR);
}
DumpFile("NETWORK DEV INFO", "/proc/net/dev");
@@ -1076,18 +1073,18 @@
RunCommand("LAST RADIO LOG", {"parse_radio_log", "/proc/last_radio_log"});
- dprintf(STDOUT_FILENO, "------ BACKLIGHTS ------\n");
- dprintf(STDOUT_FILENO, "LCD brightness=");
+ printf("------ BACKLIGHTS ------\n");
+ printf("LCD brightness=");
DumpFile("", "/sys/class/leds/lcd-backlight/brightness");
- dprintf(STDOUT_FILENO, "Button brightness=");
+ printf("Button brightness=");
DumpFile("", "/sys/class/leds/button-backlight/brightness");
- dprintf(STDOUT_FILENO, "Keyboard brightness=");
+ printf("Keyboard brightness=");
DumpFile("", "/sys/class/leds/keyboard-backlight/brightness");
- dprintf(STDOUT_FILENO, "ALS mode=");
+ printf("ALS mode=");
DumpFile("", "/sys/class/leds/lcd-backlight/als");
- dprintf(STDOUT_FILENO, "LCD driver registers:\n");
+ printf("LCD driver registers:\n");
DumpFile("", "/sys/class/leds/lcd-backlight/registers");
- dprintf(STDOUT_FILENO, "\n");
+ printf("\n");
/* Binder state is expensive to look at as it uses a lot of memory. */
DumpFile("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
@@ -1112,16 +1109,16 @@
RunCommand("DUMP VENDOR RIL LOGS", {"vril-dump"}, options.Build());
}
- dprintf(STDOUT_FILENO, "========================================================\n");
- dprintf(STDOUT_FILENO, "== Android Framework Services\n");
- dprintf(STDOUT_FILENO, "========================================================\n");
+ printf("========================================================\n");
+ printf("== Android Framework Services\n");
+ printf("========================================================\n");
RunDumpsys("DUMPSYS", {"--skip", "meminfo", "cpuinfo"}, CommandOptions::WithTimeout(90).Build(),
10);
- dprintf(STDOUT_FILENO, "========================================================\n");
- dprintf(STDOUT_FILENO, "== Checkins\n");
- dprintf(STDOUT_FILENO, "========================================================\n");
+ printf("========================================================\n");
+ printf("== Checkins\n");
+ printf("========================================================\n");
RunDumpsys("CHECKIN BATTERYSTATS", {"batterystats", "-c"});
RunDumpsys("CHECKIN MEMINFO", {"meminfo", "--checkin"});
@@ -1130,21 +1127,21 @@
RunDumpsys("CHECKIN USAGESTATS", {"usagestats", "-c"});
RunDumpsys("CHECKIN PACKAGE", {"package", "--checkin"});
- dprintf(STDOUT_FILENO, "========================================================\n");
- dprintf(STDOUT_FILENO, "== Running Application Activities\n");
- dprintf(STDOUT_FILENO, "========================================================\n");
+ printf("========================================================\n");
+ printf("== Running Application Activities\n");
+ printf("========================================================\n");
RunDumpsys("APP ACTIVITIES", {"activity", "all"});
- dprintf(STDOUT_FILENO, "========================================================\n");
- dprintf(STDOUT_FILENO, "== Running Application Services\n");
- dprintf(STDOUT_FILENO, "========================================================\n");
+ printf("========================================================\n");
+ printf("== Running Application Services\n");
+ printf("========================================================\n");
RunDumpsys("APP SERVICES", {"activity", "service", "all"});
- dprintf(STDOUT_FILENO, "========================================================\n");
- dprintf(STDOUT_FILENO, "== Running Application Providers\n");
- dprintf(STDOUT_FILENO, "========================================================\n");
+ printf("========================================================\n");
+ printf("== Running Application Providers\n");
+ printf("========================================================\n");
RunDumpsys("APP PROVIDERS", {"activity", "provider", "all"});
@@ -1153,20 +1150,19 @@
// collected.
DumpModemLogs();
- dprintf(STDOUT_FILENO, "========================================================\n");
- dprintf(STDOUT_FILENO, "== Final progress (pid %d): %d/%d (estimated %d)\n", ds.pid_,
- ds.progress_->Get(), ds.progress_->GetMax(), ds.progress_->GetInitialMax());
- dprintf(STDOUT_FILENO, "========================================================\n");
- dprintf(STDOUT_FILENO, "== dumpstate: done (id %d)\n", ds.id_);
- dprintf(STDOUT_FILENO, "========================================================\n");
+ printf("========================================================\n");
+ printf("== Final progress (pid %d): %d/%d (estimated %d)\n", ds.pid_, ds.progress_->Get(),
+ ds.progress_->GetMax(), ds.progress_->GetInitialMax());
+ printf("========================================================\n");
+ printf("== dumpstate: done (id %d)\n", ds.id_);
+ printf("========================================================\n");
}
void Dumpstate::DumpstateBoard() {
DurationReporter duration_reporter("dumpstate_board()");
- dprintf(STDOUT_FILENO, "========================================================\n");
- dprintf(STDOUT_FILENO, "== Board\n");
- dprintf(STDOUT_FILENO, "========================================================\n");
- fsync(STDOUT_FILENO);
+ printf("========================================================\n");
+ printf("== Board\n");
+ printf("========================================================\n");
android::sp<android::hardware::dumpstate::V1_0::IDumpstateDevice> dumpstate_device(
android::hardware::dumpstate::V1_0::IDumpstateDevice::getService("DumpstateDevice"));
@@ -1204,8 +1200,7 @@
dumpstate_device->dumpstateBoard(handle);
AddZipEntry("dumpstate-board.txt", path);
- dprintf(STDOUT_FILENO, "*** See dumpstate-board.txt entry ***\n");
- fsync(STDOUT_FILENO);
+ printf("*** See dumpstate-board.txt entry ***\n");
native_handle_close(handle);
native_handle_delete(handle);
@@ -1632,6 +1627,10 @@
ds.tmp_path_.c_str(), strerror(errno));
}
}
+
+ // Don't buffer stdout
+ setvbuf(stdout, nullptr, _IONBF, 0);
+
// NOTE: there should be no stdout output until now, otherwise it would break the header.
// In particular, DurationReport objects should be created passing 'title, NULL', so their
// duration is logged into MYLOG instead.