#Centipede Improve failure logging in `Command`
PiperOrigin-RevId: 547973812
diff --git a/centipede/BUILD b/centipede/BUILD
index 0d82b62..a24a8d8 100644
--- a/centipede/BUILD
+++ b/centipede/BUILD
@@ -486,6 +486,7 @@
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
+ "@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
],
)
diff --git a/centipede/command.cc b/centipede/command.cc
index cba1748..6ecca82 100644
--- a/centipede/command.cc
+++ b/centipede/command.cc
@@ -36,6 +36,7 @@
#include "absl/strings/str_join.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/str_split.h"
+#include "absl/synchronization/mutex.h"
#include "absl/time/clock.h"
#include "./centipede/logging.h"
#include "./centipede/util.h"
@@ -374,8 +375,17 @@
}
void Command::LogProblemInfo(std::string_view message) const {
- PLOG(ERROR) << message;
- LOG(ERROR).NoPrefix() << VV(command_line_);
+ // Prevent confusing interlaced logs when multiple threads experience failures
+ // at the same time.
+ // TODO(ussuri): Non-failure related logs from other threads may still
+ // interlace with these. Improve further, if possible. Note the printiing
+ // line-by-line is unavoidable to overcome the single log line length limit.
+ static absl::Mutex mu{absl::kConstInit};
+ absl::MutexLock lock(&mu);
+
+ LOG(ERROR) << message;
+ LOG(ERROR).NoPrefix() << "=== COMMAND ===";
+ LOG(ERROR).NoPrefix() << command_line_;
LOG(ERROR).NoPrefix() << "=== STDOUT ===";
for (const auto &line : absl::StrSplit(ReadRedirectedStdout(), '\n')) {
LOG(ERROR).NoPrefix() << line;
diff --git a/centipede/command.h b/centipede/command.h
index 6e40fc7..48c8557 100644
--- a/centipede/command.h
+++ b/centipede/command.h
@@ -37,8 +37,8 @@
// `path`: path to the binary.
// `args`: arguments.
// `env`: environment variables/values (in the form "KEY=VALUE").
- // `out`: stdout redirect path (empty means none).
- // `err`: stderr redirect path (empty means none).
+ // `out`: stdout redirect path (empty means use parent's STDOUT).
+ // `err`: stderr redirect path (empty means use parent's STDERR).
// `timeout`: terminate a fork server execution attempt after this duration.
// `temp_file_path`: "@@" in `path` will be replaced with `temp_file_path`.
// If `out` == `err` and both are non-empty, stdout/stderr are combined.