liblog: logprint: report truncated event log contents if error

We need to accept that a log tag can contain no payload.  For those
that are corrupted, and to aid debugging, report what we did manage
to interpret.  Report last character as a ! for corruption, and ^
for truncation.  Fix a few Android Coding standard issues.

Test: gTest logcat-unit-tests
Bug: 32903864
Change-Id: Id11bef3a7b6569305c51701dd66c45d2038d6628
This commit is contained in:
Mark Salyzyn 2016-11-11 14:41:30 -08:00
parent 787482ecd9
commit 1a57ae3a7d
2 changed files with 57 additions and 58 deletions

View File

@ -632,8 +632,8 @@ static int android_log_printBinaryEvent(const unsigned char** pEventData,
size_t len;
int64_t lval;
if (eventDataLen < 1)
return -1;
if (eventDataLen < 1) return -1;
type = *eventData++;
eventDataLen--;
@ -729,8 +729,7 @@ static int android_log_printBinaryEvent(const unsigned char** pEventData,
{
int32_t ival;
if (eventDataLen < 4)
return -1;
if (eventDataLen < 4) return -1;
ival = get4LE(eventData);
eventData += 4;
eventDataLen -= 4;
@ -740,8 +739,7 @@ static int android_log_printBinaryEvent(const unsigned char** pEventData,
goto pr_lval;
case EVENT_TYPE_LONG:
/* 64-bit signed long */
if (eventDataLen < 8)
return -1;
if (eventDataLen < 8) return -1;
lval = get8LE(eventData);
eventData += 8;
eventDataLen -= 8;
@ -761,8 +759,7 @@ static int android_log_printBinaryEvent(const unsigned char** pEventData,
uint32_t ival;
float fval;
if (eventDataLen < 4)
return -1;
if (eventDataLen < 4) return -1;
ival = get4LE(eventData);
fval = *(float*)&ival;
eventData += 4;
@ -783,14 +780,12 @@ static int android_log_printBinaryEvent(const unsigned char** pEventData,
{
unsigned int strLen;
if (eventDataLen < 4)
return -1;
if (eventDataLen < 4) return -1;
strLen = get4LE(eventData);
eventData += 4;
eventDataLen -= 4;
if (eventDataLen < strLen)
return -1;
if (eventDataLen < strLen) return -1;
if (cp && (strLen == 0)) {
/* reset the format if no content */
@ -818,41 +813,32 @@ static int android_log_printBinaryEvent(const unsigned char** pEventData,
unsigned char count;
int i;
if (eventDataLen < 1)
return -1;
if (eventDataLen < 1) return -1;
count = *eventData++;
eventDataLen--;
if (outBufLen > 0) {
*outBuf++ = '[';
outBufLen--;
} else {
goto no_room;
}
if (outBufLen <= 0) goto no_room;
*outBuf++ = '[';
outBufLen--;
for (i = 0; i < count; i++) {
result = android_log_printBinaryEvent(&eventData, &eventDataLen,
&outBuf, &outBufLen, fmtStr, fmtLen);
if (result != 0)
goto bail;
if (result != 0) goto bail;
if (i < count-1) {
if (outBufLen > 0) {
*outBuf++ = ',';
outBufLen--;
} else {
goto no_room;
}
if (i < (count - 1)) {
if (outBufLen <= 0) goto no_room;
*outBuf++ = ',';
outBufLen--;
}
}
if (outBufLen > 0) {
*outBuf++ = ']';
outBufLen--;
} else {
goto no_room;
}
if (outBufLen <= 0) goto no_room;
*outBuf++ = ']';
outBufLen--;
}
break;
default:
@ -997,8 +983,7 @@ LIBLOG_ABI_PUBLIC int android_log_processBinaryLogBuffer(
}
}
inCount = buf->len;
if (inCount < 4)
return -1;
if (inCount < 4) return -1;
tagIndex = get4LE(eventData);
eventData += 4;
inCount -= 4;
@ -1031,16 +1016,20 @@ LIBLOG_ABI_PUBLIC int android_log_processBinaryLogBuffer(
/*
* Format the event log data into the buffer.
*/
char* outBuf = messageBuf;
size_t outRemaining = messageBufLen - 1; /* leave one for nul byte */
int result;
const char* fmtStr = NULL;
size_t fmtLen = 0;
if (descriptive_output && map) {
fmtStr = android_lookupEventFormat_len(map, &fmtLen, tagIndex);
}
result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf,
&outRemaining, &fmtStr, &fmtLen);
char* outBuf = messageBuf;
size_t outRemaining = messageBufLen - 1; /* leave one for nul byte */
int result = 0;
if ((inCount > 0) || fmtLen) {
result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf,
&outRemaining, &fmtStr, &fmtLen);
}
if ((result == 1) && fmtStr) {
/* We overflowed :-(, let's repaint the line w/o format dressings */
eventData = (const unsigned char*)buf->msg;
@ -1055,17 +1044,16 @@ LIBLOG_ABI_PUBLIC int android_log_processBinaryLogBuffer(
}
if (result < 0) {
fprintf(stderr, "Binary log entry conversion failed\n");
return -1;
} else if (result == 1) {
if (outBuf > messageBuf) {
/* leave an indicator */
*(outBuf-1) = '!';
} else {
/* no room to output anything at all */
*outBuf++ = '!';
outRemaining--;
}
if (result) {
if (!outRemaining) {
/* make space to leave an indicator */
--outBuf;
++outRemaining;
}
/* pretend we ate all the data */
*outBuf++ = (result < 0) ? '!' : '^'; /* Error or Truncation? */
outRemaining--;
/* pretend we ate all the data to prevent log stutter */
inCount = 0;
}
@ -1802,8 +1790,7 @@ LIBLOG_ABI_PUBLIC int android_log_printLogLine(
outBuffer = android_log_formatLogLine(p_format, defaultBuffer,
sizeof(defaultBuffer), entry, &totalLen);
if (!outBuffer)
return -1;
if (!outBuffer) return -1;
do {
ret = write(fd, outBuffer, totalLen);

View File

@ -1255,19 +1255,25 @@ static bool End_to_End(const char* tag, const char* fmt, ...) {
va_end(ap);
char *str = NULL;
asprintf(&str, "I/%s ( %%d): %s%%c", tag, buffer);
asprintf(&str, "I/%s ( %%d):%%c%s%%c", tag, buffer);
std::string expect(str);
free(str);
int count = 0;
pid_t pid = getpid();
std::string lastMatch;
int maxMatch = 1;
while (fgets(buffer, sizeof(buffer), fp)) {
char space;
char newline;
int p;
int ret = sscanf(buffer, expect.c_str(), &p, &newline);
if ((2 == ret) && (p == pid) && (newline == '\n')) ++count;
else if ((1 == ret) && (p == pid) && (count == 0)) lastMatch = buffer;
int ret = sscanf(buffer, expect.c_str(), &p, &space, &newline);
if ((ret == 3) && (p == pid) && (space == ' ') && (newline == '\n')) {
++count;
} else if ((ret >= maxMatch) && (p == pid) && (count == 0)) {
lastMatch = buffer;
maxMatch = ret;
}
}
pclose(fp);
@ -1395,4 +1401,10 @@ TEST(logcat, descriptive) {
}
}
{
static const struct tag sync = { 27501, "notification_panel_hidden" };
android_log_event_context ctx(sync.tagNo);
ctx.write();
EXPECT_TRUE(End_to_End(sync.tagStr, ""));
}
}