KernelLogger: Truncate lines that are too long
Instead of dropping the entire message, truncate the message and log a
"previous message missing {} bytes" message.
Test: Apply I85bd738334ce15a316c7d469deb1c6083affd98a and observe
"adb logcat -b kernel"
Change-Id: Ia4efd3f6fe55d0c869fb2f46741abfbf2b488108
diff --git a/logging.cpp b/logging.cpp
index 81269dd..4942e2f 100644
--- a/logging.cpp
+++ b/logging.cpp
@@ -32,10 +32,6 @@
#include <errno.h>
#endif
-#if defined(__linux__)
-#include <sys/uio.h>
-#endif
-
#include <atomic>
#include <iostream>
#include <limits>
@@ -258,20 +254,19 @@
// The kernel's printk buffer is only |1024 - PREFIX_MAX| bytes, where
// PREFIX_MAX could be 48 or 32.
// Reference: kernel/printk/printk.c
- // TODO: should we automatically break up long lines into multiple lines?
- // Or we could log but with something like "..." at the end?
static constexpr int LOG_LINE_MAX = 1024 - 48;
char buf[LOG_LINE_MAX] __attribute__((__uninitialized__));
size_t size = snprintf(buf, sizeof(buf), "<%d>%s: %.*s\n", level, tag, length, msg);
- if (size > sizeof(buf)) {
- size = snprintf(buf, sizeof(buf), "<%d>%s: %zu-byte message too long for printk\n",
- level, tag, size);
- }
+ TEMP_FAILURE_RETRY(write(klog_fd, buf, std::min(size, sizeof(buf))));
- iovec iov[1];
- iov[0].iov_base = buf;
- iov[0].iov_len = size;
- TEMP_FAILURE_RETRY(writev(klog_fd, iov, 1));
+ if (size > sizeof(buf)) {
+ size_t truncated = size - sizeof(buf);
+ size = snprintf(
+ buf, sizeof(buf),
+ "<%d>%s: **previous message missing %zu bytes** %zu-byte message too long for printk\n",
+ level, tag, truncated, size);
+ TEMP_FAILURE_RETRY(write(klog_fd, buf, std::min(size, sizeof(buf))));
+ }
}
void KernelLogger(android::base::LogId, android::base::LogSeverity severity, const char* tag,