From ee49c6a670a54e0636f81f39ddc93c87c9a4d766 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Fri, 12 Jun 2015 14:59:42 -0700 Subject: logd: missing klogd content - regression in log_strtok_r (part deux) In commit 'logd: fix kernel logline stutter' 2c3b300fd8307e8da13608197d0a89bc613de5fb we introduced log_strtok_r. as a replacement for strtok_r that dealt with a problem with some kernel log messages. Fix is to refine definition of is_timestamp to not match on patterns like [0], requiring a single period. Another fix is to refine definition of is_prio to properly escape non-digit content. - Missing content because SYSLOG_ACTION_SIZE_BUFFER with added logging is too short for full read of SYSLOG_ACTION_READ_ALL dropping initial content. Add a margin for additional 1024 bytes. - Absolute _first_ log entry has sequence number of 1, which is specifically dropped, start sequence count at 1 rather than 0. - Remove trailing space for efficiency. - If tag exists but no content, trick into kernel logging. Bug: 21851884 Change-Id: I0867a555a3bca09bbf18d18e75e41dffffe57a23 --- logd/LogKlog.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'logd/LogKlog.cpp') diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp index 7d1464899..d578c04db 100644 --- a/logd/LogKlog.cpp +++ b/logd/LogKlog.cpp @@ -45,8 +45,8 @@ static char *is_prio(char *s) { } char c; while ((c = *s++)) { - if (!isdigit(c) && (c == '>')) { - return s; + if (!isdigit(c)) { + return (c == '>') ? s : NULL; } } return NULL; @@ -65,17 +65,15 @@ static char *is_timestamp(char *s) { while ((c = *s++)) { if ((c == '.') && first_period) { first_period = false; - continue; - } - if (!isdigit(c) && (c == ']')) { - return s; + } else if (!isdigit(c)) { + return ((c == ']') && !first_period && (*s == ' ')) ? s : NULL; } } return NULL; } // Like strtok_r with "\r\n" except that we look for log signatures (regex) -// \(\(<[0-9]+>\)\([[] *[0-9]+[]]\)\{0,1\}\|[[] *[0-9]+[]]\) +// \(\(<[0-9]+>\)\([[] *[0-9]+[.][0-9]+[]] \)\{0,1\}\|[[] *[0-9]+[.][0-9]+[]] \) // and split if we see a second one without a newline. #define SIGNATURE_MASK 0xF0 @@ -547,10 +545,21 @@ int LogKlog::log(const char *buf) { } } size_t l = etag - tag; + // skip leading space while (isspace(*buf)) { ++buf; } - size_t n = 1 + l + 1 + strlen(buf) + 1; + // truncate trailing space + size_t b = strlen(buf); + while (b && isspace(buf[b-1])) { + --b; + } + // trick ... allow tag with empty content to be logged. log() drops empty + if (!b && l) { + buf = " "; + b = 1; + } + size_t n = 1 + l + 1 + b + 1; // Allocate a buffer to hold the interpreted log message int rc = n; @@ -572,7 +581,8 @@ int LogKlog::log(const char *buf) { ++np; // Copy main message to the remainder - strcpy(np, buf); + strncpy(np, buf, b); + np[b] = '\0'; // Log message rc = logbuf->log(LOG_ID_KERNEL, now, uid, pid, tid, newstr, -- cgit v1.2.3