summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--liblog/Android.bp1
-rw-r--r--liblog/config_write.c23
-rw-r--r--liblog/include/log/log_frontend.h11
-rw-r--r--liblog/logger_write.c6
-rw-r--r--liblog/stderr_write.c219
-rw-r--r--liblog/tests/Android.mk2
-rw-r--r--liblog/tests/liblog_test.cpp215
-rw-r--r--liblog/tests/liblog_test_stderr.cpp5
-rw-r--r--liblog/tests/liblog_test_stderr_local.cpp4
9 files changed, 428 insertions, 58 deletions
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 310dbf4c3..bb8c3af2b 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -26,6 +26,7 @@ liblog_sources = [
26 "logger_read.c", 26 "logger_read.c",
27 "logger_write.c", 27 "logger_write.c",
28 "logprint.c", 28 "logprint.c",
29 "stderr_write.c",
29] 30]
30liblog_host_sources = [ 31liblog_host_sources = [
31 "fake_log_device.c", 32 "fake_log_device.c",
diff --git a/liblog/config_write.c b/liblog/config_write.c
index 583dcff3a..6a6c2205d 100644
--- a/liblog/config_write.c
+++ b/liblog/config_write.c
@@ -78,6 +78,29 @@ LIBLOG_HIDDEN void __android_log_config_write() {
78 &fakeLoggerWrite); 78 &fakeLoggerWrite);
79#endif 79#endif
80 } 80 }
81
82 if (__android_log_frontend & LOGGER_STDERR) {
83 extern struct android_log_transport_write stderrLoggerWrite;
84
85 /*
86 * stderr logger should be primary if we can be the only one, or if
87 * already in the primary list. Otherwise land in the persist list.
88 * Remember we can be called here if we are already initialized.
89 */
90 if (list_empty(&__android_log_transport_write)) {
91 __android_log_add_transport(&__android_log_transport_write,
92 &stderrLoggerWrite);
93 } else {
94 struct android_log_transport_write *transp;
95 write_transport_for_each(transp, &__android_log_transport_write) {
96 if (transp == &stderrLoggerWrite) {
97 return;
98 }
99 }
100 __android_log_add_transport(&__android_log_persist_write,
101 &stderrLoggerWrite);
102 }
103 }
81} 104}
82 105
83LIBLOG_HIDDEN void __android_log_config_write_close() { 106LIBLOG_HIDDEN void __android_log_config_write_close() {
diff --git a/liblog/include/log/log_frontend.h b/liblog/include/log/log_frontend.h
index 952777971..5efa548af 100644
--- a/liblog/include/log/log_frontend.h
+++ b/liblog/include/log/log_frontend.h
@@ -17,11 +17,12 @@ extern "C" {
17/* 17/*
18 * Logging frontends, bit mask to select features. Function returns selection. 18 * Logging frontends, bit mask to select features. Function returns selection.
19 */ 19 */
20#define LOGGER_DEFAULT 0x0 20#define LOGGER_DEFAULT 0x00
21#define LOGGER_LOGD 0x1 21#define LOGGER_LOGD 0x01
22#define LOGGER_KERNEL 0x2 /* Reserved/Deprecated */ 22#define LOGGER_KERNEL 0x02 /* Reserved/Deprecated */
23#define LOGGER_NULL 0x4 /* Does not release resources of other selections */ 23#define LOGGER_NULL 0x04 /* Does not release resources of other selections */
24#define LOGGER_LOCAL 0x8 /* logs sent to local memory */ 24#define LOGGER_LOCAL 0x08 /* logs sent to local memory */
25#define LOGGER_STDERR 0x10 /* logs sent to stderr */
25 26
26/* Both return the selected frontend flag mask, or negative errno */ 27/* Both return the selected frontend flag mask, or negative errno */
27int android_set_log_frontend(int frontend_flag); 28int android_set_log_frontend(int frontend_flag);
diff --git a/liblog/logger_write.c b/liblog/logger_write.c
index e149e682f..2a9710164 100644
--- a/liblog/logger_write.c
+++ b/liblog/logger_write.c
@@ -664,9 +664,9 @@ LIBLOG_ABI_PUBLIC int android_set_log_frontend(int frontend_flag)
664 return retval; 664 return retval;
665 } 665 }
666 666
667 __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD; 667 __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
668 668
669 frontend_flag &= LOGGER_LOCAL | LOGGER_LOGD; 669 frontend_flag &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
670 670
671 if (__android_log_frontend != frontend_flag) { 671 if (__android_log_frontend != frontend_flag) {
672 __android_log_frontend = frontend_flag; 672 __android_log_frontend = frontend_flag;
@@ -695,7 +695,7 @@ LIBLOG_ABI_PUBLIC int android_get_log_frontend()
695 if (write_to_log == __write_to_log_null) { 695 if (write_to_log == __write_to_log_null) {
696 ret = LOGGER_NULL; 696 ret = LOGGER_NULL;
697 } else { 697 } else {
698 __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD; 698 __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
699 ret = __android_log_frontend; 699 ret = __android_log_frontend;
700 if ((write_to_log != __write_to_log_init) && 700 if ((write_to_log != __write_to_log_init) &&
701 (write_to_log != __write_to_log_daemon)) { 701 (write_to_log != __write_to_log_daemon)) {
diff --git a/liblog/stderr_write.c b/liblog/stderr_write.c
new file mode 100644
index 000000000..b73929923
--- /dev/null
+++ b/liblog/stderr_write.c
@@ -0,0 +1,219 @@
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * stderr write handler. Output is logcat-like, and responds to
19 * logcat's environment variables ANDROID_PRINTF_LOG and
20 * ANDROID_LOG_TAGS to filter output.
21 *
22 * This transport only provides a writer, that means that it does not
23 * provide an End-To-End capability as the logs are effectively _lost_
24 * to the stderr file stream. The purpose of this transport is to
25 * supply a means for command line tools to report their logging
26 * to the stderr stream, in line with all other activities.
27 */
28
29#include <errno.h>
30#include <stdbool.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <sys/types.h>
35#include <unistd.h>
36
37#include <log/event_tag_map.h>
38#include <log/log.h>
39#include <log/logprint.h>
40#include <log/uio.h>
41
42#include "log_portability.h"
43#include "logger.h"
44
45static int stderrOpen();
46static void stderrClose();
47static int stderrAvailable(log_id_t logId);
48static int stderrWrite(log_id_t logId, struct timespec* ts,
49 struct iovec* vec, size_t nr);
50
51struct stderrContext {
52 AndroidLogFormat* logformat;
53#if defined(__ANDROID__)
54 EventTagMap* eventTagMap;
55#endif
56};
57
58LIBLOG_HIDDEN struct android_log_transport_write stderrLoggerWrite = {
59 .node = { &stderrLoggerWrite.node, &stderrLoggerWrite.node },
60 .context.private = NULL,
61 .name = "stderr",
62 .available = stderrAvailable,
63 .open = stderrOpen,
64 .close = stderrClose,
65 .write = stderrWrite,
66};
67
68static int stderrOpen()
69{
70 struct stderrContext* ctx;
71 const char* envStr;
72 bool setFormat;
73
74 if (!stderr || (fileno(stderr) < 0)) {
75 return -EBADF;
76 }
77
78 if (stderrLoggerWrite.context.private) {
79 return fileno(stderr);
80 }
81
82 ctx = calloc(1, sizeof(struct stderrContext));
83 if (!ctx) {
84 return -ENOMEM;
85 }
86
87 ctx->logformat = android_log_format_new();
88 if (!ctx->logformat) {
89 free(ctx);
90 return -ENOMEM;
91 }
92
93 envStr = getenv("ANDROID_PRINTF_LOG");
94 setFormat = false;
95
96 if (envStr) {
97 char* formats = strdup(envStr);
98 char* sv = NULL;
99 char* arg = formats;
100 while (!!(arg = strtok_r(arg, ",:; \t\n\r\f", &sv))) {
101 AndroidLogPrintFormat format = android_log_formatFromString(arg);
102 arg = NULL;
103 if (format == FORMAT_OFF) {
104 continue;
105 }
106 if (android_log_setPrintFormat(ctx->logformat, format) <= 0) {
107 continue;
108 }
109 setFormat = true;
110 }
111 free(formats);
112 }
113 if (!setFormat) {
114 AndroidLogPrintFormat format = android_log_formatFromString(
115 "threadtime");
116 android_log_setPrintFormat(ctx->logformat, format);
117 }
118 envStr = getenv("ANDROID_LOG_TAGS");
119 if (envStr) {
120 android_log_addFilterString(ctx->logformat, envStr);
121 }
122 stderrLoggerWrite.context.private = ctx;
123
124 return fileno(stderr);
125}
126
127static void stderrClose()
128{
129 struct stderrContext* ctx = stderrLoggerWrite.context.private;
130
131 if (ctx) {
132 stderrLoggerWrite.context.private = NULL;
133 if (ctx->logformat) {
134 android_log_format_free(ctx->logformat);
135 ctx->logformat = NULL;
136 }
137#if defined(__ANDROID__)
138 if (ctx->eventTagMap) {
139 android_closeEventTagMap(ctx->eventTagMap);
140 ctx->eventTagMap = NULL;
141 }
142#endif
143 }
144}
145
146static int stderrAvailable(log_id_t logId)
147{
148 if ((logId >= LOG_ID_MAX) || (logId == LOG_ID_KERNEL)) {
149 return -EINVAL;
150 }
151 return 1;
152}
153
154static int stderrWrite(log_id_t logId, struct timespec* ts,
155 struct iovec* vec, size_t nr)
156{
157 struct log_msg log_msg;
158 AndroidLogEntry entry;
159 char binaryMsgBuf[1024];
160 int err;
161 size_t i;
162 struct stderrContext* ctx = stderrLoggerWrite.context.private;
163
164 if (!ctx) return -EBADF;
165 if (!vec || !nr) return -EINVAL;
166
167 log_msg.entry.len = 0;
168 log_msg.entry.hdr_size = sizeof(log_msg.entry);
169 log_msg.entry.pid = getpid();
170#ifdef __BIONIC__
171 log_msg.entry.tid = gettid();
172#else
173 log_msg.entry.tid = getpid();
174#endif
175 log_msg.entry.sec = ts->tv_sec;
176 log_msg.entry.nsec = ts->tv_nsec;
177 log_msg.entry.lid = logId;
178 log_msg.entry.uid = __android_log_uid();
179
180 for (i = 0; i < nr; ++i) {
181 size_t len = vec[i].iov_len;
182 if ((log_msg.entry.len + len) > LOGGER_ENTRY_MAX_PAYLOAD) {
183 len = LOGGER_ENTRY_MAX_PAYLOAD - log_msg.entry.len;
184 }
185 if (!len) continue;
186 memcpy(log_msg.entry.msg + log_msg.entry.len, vec[i].iov_base, len);
187 log_msg.entry.len += len;
188 }
189
190 if ((logId == LOG_ID_EVENTS) || (logId == LOG_ID_SECURITY)) {
191#if defined(__ANDROID__)
192 if (!ctx->eventTagMap) {
193 ctx->eventTagMap = android_openEventTagMap(NULL);
194 }
195#endif
196 err = android_log_processBinaryLogBuffer(&log_msg.entry_v1,
197 &entry,
198#if defined(__ANDROID__)
199 ctx->eventTagMap,
200#else
201 NULL,
202#endif
203 binaryMsgBuf,
204 sizeof(binaryMsgBuf));
205 } else {
206 err = android_log_processLogBuffer(&log_msg.entry_v1, &entry);
207 }
208
209 /* print known truncated data, in essence logcat --debug */
210 if ((err < 0) && !entry.message) return -EINVAL;
211
212 if (!android_log_shouldPrintLine(ctx->logformat, entry.tag, entry.priority)) {
213 return log_msg.entry.len;
214 }
215
216 err = android_log_printLogLine(ctx->logformat, fileno(stderr), &entry);
217 if (err < 0) return errno ? -errno : -EINVAL;
218 return log_msg.entry.len;
219}
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index cfea45202..0e6432ced 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -57,6 +57,8 @@ test_c_flags := \
57test_src_files := \ 57test_src_files := \
58 liblog_test_default.cpp \ 58 liblog_test_default.cpp \
59 liblog_test_local.cpp \ 59 liblog_test_local.cpp \
60 liblog_test_stderr.cpp \
61 liblog_test_stderr_local.cpp \
60 log_id_test.cpp \ 62 log_id_test.cpp \
61 log_radio_test.cpp \ 63 log_radio_test.cpp \
62 log_read_test.cpp \ 64 log_read_test.cpp \
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index bc0ea4c25..2537fac23 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -47,7 +47,7 @@
47#endif 47#endif
48#endif 48#endif
49 49
50#if (!defined(USING_LOGGER_DEFAULT) || !defined(USING_LOGGER_LOCAL)) 50#if (!defined(USING_LOGGER_DEFAULT) || !defined(USING_LOGGER_LOCAL) || !defined(USING_LOGGER_STDERR))
51#ifdef liblog // a binary clue that we are overriding the test names 51#ifdef liblog // a binary clue that we are overriding the test names
52// Does not support log reading blocking feature yet 52// Does not support log reading blocking feature yet
53// Does not support LOG_ID_SECURITY (unless we set LOGGER_LOCAL | LOGGER_LOGD) 53// Does not support LOG_ID_SECURITY (unless we set LOGGER_LOCAL | LOGGER_LOGD)
@@ -62,6 +62,11 @@
62#define USING_LOGGER_DEFAULT 62#define USING_LOGGER_DEFAULT
63#endif 63#endif
64#endif 64#endif
65#ifdef USING_LOGGER_STDERR
66# define SUPPORTS_END_TO_END 0
67#else
68# define SUPPORTS_END_TO_END 1
69#endif
65 70
66// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and 71// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
67// non-syscall libs. Since we are only using this in the emergency of 72// non-syscall libs. Since we are only using this in the emergency of
@@ -98,7 +103,7 @@ TEST(liblog, __android_log_btwrite) {
98 usleep(1000); 103 usleep(1000);
99} 104}
100 105
101#if (defined(__ANDROID__) && !defined(USING_LOGGER_LOCAL)) 106#if (defined(__ANDROID__) && defined(USING_LOGGER_DEFAULT))
102static std::string popenToString(std::string command) { 107static std::string popenToString(std::string command) {
103 std::string ret; 108 std::string ret;
104 109
@@ -176,8 +181,8 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
176 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); 181 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
177 182
178 log_time ts(CLOCK_MONOTONIC); 183 log_time ts(CLOCK_MONOTONIC);
179 ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); 184 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
180#ifndef USING_LOGGER_LOCAL 185#ifdef USING_LOGGER_DEFAULT
181 // Check that we can close and reopen the logger 186 // Check that we can close and reopen the logger
182 bool pmsgActiveAfter__android_log_btwrite; 187 bool pmsgActiveAfter__android_log_btwrite;
183 bool logdwActiveAfter__android_log_btwrite; 188 bool logdwActiveAfter__android_log_btwrite;
@@ -200,8 +205,8 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
200#endif 205#endif
201 206
202 log_time ts1(CLOCK_MONOTONIC); 207 log_time ts1(CLOCK_MONOTONIC);
203 ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1))); 208 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
204#ifndef USING_LOGGER_LOCAL 209#ifdef USING_LOGGER_DEFAULT
205 if (getuid() == AID_ROOT) { 210 if (getuid() == AID_ROOT) {
206 pmsgActiveAfter__android_log_btwrite = isPmsgActive(); 211 pmsgActiveAfter__android_log_btwrite = isPmsgActive();
207 logdwActiveAfter__android_log_btwrite = isLogdwActive(); 212 logdwActiveAfter__android_log_btwrite = isLogdwActive();
@@ -220,7 +225,7 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
220 break; 225 break;
221 } 226 }
222 227
223 ASSERT_EQ(log_msg.entry.pid, pid); 228 EXPECT_EQ(log_msg.entry.pid, pid);
224 229
225 if ((log_msg.entry.len != sizeof(android_log_event_long_t)) 230 if ((log_msg.entry.len != sizeof(android_log_event_long_t))
226 || (log_msg.id() != LOG_ID_EVENTS)) { 231 || (log_msg.id() != LOG_ID_EVENTS)) {
@@ -242,8 +247,8 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
242 } 247 }
243 } 248 }
244 249
245 EXPECT_EQ(1, count); 250 EXPECT_EQ(SUPPORTS_END_TO_END, count);
246 EXPECT_EQ(1, second_count); 251 EXPECT_EQ(SUPPORTS_END_TO_END, second_count);
247 252
248 android_logger_list_close(logger_list); 253 android_logger_list_close(logger_list);
249#else 254#else
@@ -251,6 +256,54 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
251#endif 256#endif
252} 257}
253 258
259#if (defined(__ANDROID__) || defined(USING_LOGGER_LOCAL))
260static void print_frontend(const char* prefix, int logger) {
261 static const char orstr[] = " | ";
262
263 if (!prefix) {
264 prefix = "";
265 }
266 if (logger < 0) {
267 fprintf(stderr, "%s%s\n", prefix, strerror(-logger));
268 return;
269 }
270
271 if (logger == LOGGER_DEFAULT) {
272 fprintf(stderr, "%sLOGGER_DEFAULT", prefix);
273 prefix = orstr;
274 }
275 if (logger & LOGGER_LOGD) {
276 fprintf(stderr, "%sLOGGER_LOGD", prefix);
277 prefix = orstr;
278 }
279 if (logger & LOGGER_KERNEL) {
280 fprintf(stderr, "%sLOGGER_KERNEL", prefix);
281 prefix = orstr;
282 }
283 if (logger & LOGGER_NULL) {
284 fprintf(stderr, "%sLOGGER_NULL", prefix);
285 prefix = orstr;
286 }
287 if (logger & LOGGER_LOCAL) {
288 fprintf(stderr, "%sLOGGER_LOCAL", prefix);
289 prefix = orstr;
290 }
291 if (logger & LOGGER_STDERR) {
292 fprintf(stderr, "%sLOGGER_STDERR", prefix);
293 prefix = orstr;
294 }
295 logger &= ~(LOGGER_LOGD | LOGGER_KERNEL | LOGGER_NULL | LOGGER_LOCAL |
296 LOGGER_STDERR);
297 if (logger) {
298 fprintf(stderr, "%s0x%x", prefix, logger);
299 prefix = orstr;
300 }
301 if (prefix == orstr) {
302 fprintf(stderr, "\n");
303 }
304}
305#endif
306
254// This test makes little sense standalone, and requires the tests ahead 307// This test makes little sense standalone, and requires the tests ahead
255// and behind us, to make us whole. We could incorporate a prefix and 308// and behind us, to make us whole. We could incorporate a prefix and
256// suffix test to make this standalone, but opted to not complicate this. 309// suffix test to make this standalone, but opted to not complicate this.
@@ -261,10 +314,14 @@ TEST(liblog, android_set_log_frontend) {
261#endif 314#endif
262 315
263 int logger = android_get_log_frontend(); 316 int logger = android_get_log_frontend();
317 print_frontend("android_get_log_frontend = ", logger);
264 EXPECT_NE(LOGGER_NULL, logger); 318 EXPECT_NE(LOGGER_NULL, logger);
265 319
266 EXPECT_EQ(LOGGER_NULL, android_set_log_frontend(LOGGER_NULL)); 320 int ret;
267 EXPECT_EQ(LOGGER_NULL, android_get_log_frontend()); 321 EXPECT_EQ(LOGGER_NULL, ret = android_set_log_frontend(LOGGER_NULL));
322 print_frontend("android_set_log_frontend = ", ret);
323 EXPECT_EQ(LOGGER_NULL, ret = android_get_log_frontend());
324 print_frontend("android_get_log_frontend = ", ret);
268 325
269 pid_t pid = getpid(); 326 pid_t pid = getpid();
270 327
@@ -273,7 +330,7 @@ TEST(liblog, android_set_log_frontend) {
273 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); 330 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
274 331
275 log_time ts(CLOCK_MONOTONIC); 332 log_time ts(CLOCK_MONOTONIC);
276 ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); 333 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
277 334
278 usleep(1000000); 335 usleep(1000000);
279 336
@@ -285,7 +342,7 @@ TEST(liblog, android_set_log_frontend) {
285 break; 342 break;
286 } 343 }
287 344
288 ASSERT_EQ(log_msg.entry.pid, pid); 345 EXPECT_EQ(log_msg.entry.pid, pid);
289 346
290 if ((log_msg.entry.len != sizeof(android_log_event_long_t)) 347 if ((log_msg.entry.len != sizeof(android_log_event_long_t))
291 || (log_msg.id() != LOG_ID_EVENTS)) { 348 || (log_msg.id() != LOG_ID_EVENTS)) {
@@ -307,8 +364,10 @@ TEST(liblog, android_set_log_frontend) {
307 364
308 android_logger_list_close(logger_list); 365 android_logger_list_close(logger_list);
309 366
310 EXPECT_EQ(logger, android_set_log_frontend(logger)); 367 EXPECT_EQ(logger, ret = android_set_log_frontend(logger));
311 EXPECT_EQ(logger, android_get_log_frontend()); 368 print_frontend("android_set_log_frontend = ", ret);
369 EXPECT_EQ(logger, ret = android_get_log_frontend());
370 print_frontend("android_get_log_frontend = ", ret);
312 371
313 // False negative if liblog.__android_log_btwrite__android_logger_list_read 372 // False negative if liblog.__android_log_btwrite__android_logger_list_read
314 // fails above, so we will likely succeed. But we will have so many 373 // fails above, so we will likely succeed. But we will have so many
@@ -350,7 +409,7 @@ static void bswrite_test(const char *message) {
350 log_time ts(CLOCK_REALTIME); 409 log_time ts(CLOCK_REALTIME);
351#endif 410#endif
352 411
353 ASSERT_LT(0, __android_log_bswrite(0, message)); 412 EXPECT_LT(0, __android_log_bswrite(0, message));
354 size_t num_lines = 1, size = 0, length = 0, total = 0; 413 size_t num_lines = 1, size = 0, length = 0, total = 0;
355 const char *cp = message; 414 const char *cp = message;
356 while (*cp) { 415 while (*cp) {
@@ -382,7 +441,7 @@ static void bswrite_test(const char *message) {
382 break; 441 break;
383 } 442 }
384 443
385 ASSERT_EQ(log_msg.entry.pid, pid); 444 EXPECT_EQ(log_msg.entry.pid, pid);
386 445
387 if ((log_msg.entry.sec < (ts.tv_sec - 1)) 446 if ((log_msg.entry.sec < (ts.tv_sec - 1))
388 || ((ts.tv_sec + 1) < log_msg.entry.sec) 447 || ((ts.tv_sec + 1) < log_msg.entry.sec)
@@ -413,19 +472,26 @@ static void bswrite_test(const char *message) {
413 int processBinaryLogBuffer = android_log_processBinaryLogBuffer( 472 int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
414 &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf)); 473 &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
415 EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer); 474 EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer);
416 if (processBinaryLogBuffer == 0) { 475 if ((processBinaryLogBuffer == 0) || entry.message) {
417 size_t line_overhead = 20; 476 size_t line_overhead = 20;
418 if (pid > 99999) ++line_overhead; 477 if (pid > 99999) ++line_overhead;
419 if (pid > 999999) ++line_overhead; 478 if (pid > 999999) ++line_overhead;
420 fflush(stderr); 479 fflush(stderr);
421 EXPECT_EQ((int)((line_overhead * num_lines) + size), 480 if (processBinaryLogBuffer) {
422 android_log_printLogLine(logformat, fileno(stderr), &entry)); 481 EXPECT_GT((int)((line_overhead * num_lines) + size),
482 android_log_printLogLine(logformat,
483 fileno(stderr), &entry));
484 } else {
485 EXPECT_EQ((int)((line_overhead * num_lines) + size),
486 android_log_printLogLine(logformat,
487 fileno(stderr), &entry));
488 }
423 } 489 }
424 android_log_format_free(logformat); 490 android_log_format_free(logformat);
425 } 491 }
426 } 492 }
427 493
428 EXPECT_EQ(1, count); 494 EXPECT_EQ(SUPPORTS_END_TO_END, count);
429 495
430 android_logger_list_close(logger_list); 496 android_logger_list_close(logger_list);
431#else 497#else
@@ -527,7 +593,7 @@ static void buf_write_test(const char *message) {
527 android_log_format_free(logformat); 593 android_log_format_free(logformat);
528 } 594 }
529 595
530 EXPECT_EQ(1, count); 596 EXPECT_EQ(SUPPORTS_END_TO_END, count);
531 597
532 android_logger_list_close(logger_list); 598 android_logger_list_close(logger_list);
533#else 599#else
@@ -1058,10 +1124,14 @@ TEST(liblog, max_payload) {
1058 1124
1059 android_logger_list_close(logger_list); 1125 android_logger_list_close(logger_list);
1060 1126
1127#if SUPPORTS_END_TO_END
1061 EXPECT_EQ(true, matches); 1128 EXPECT_EQ(true, matches);
1062 1129
1063 EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len)); 1130 EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len));
1064#else 1131#else
1132 EXPECT_EQ(false, matches);
1133#endif
1134#else
1065 GTEST_LOG_(INFO) << "This test does nothing.\n"; 1135 GTEST_LOG_(INFO) << "This test does nothing.\n";
1066#endif 1136#endif
1067} 1137}
@@ -1123,7 +1193,7 @@ TEST(liblog, __android_log_buf_print__maxtag) {
1123 android_log_format_free(logformat); 1193 android_log_format_free(logformat);
1124 } 1194 }
1125 1195
1126 EXPECT_EQ(1, count); 1196 EXPECT_EQ(SUPPORTS_END_TO_END, count);
1127 1197
1128 android_logger_list_close(logger_list); 1198 android_logger_list_close(logger_list);
1129#else 1199#else
@@ -1184,6 +1254,11 @@ TEST(liblog, too_big_payload) {
1184 1254
1185 android_logger_list_close(logger_list); 1255 android_logger_list_close(logger_list);
1186 1256
1257#if !SUPPORTS_END_TO_END
1258 max_len = max_len ?
1259 max_len :
1260 LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag);
1261#endif
1187 EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag), 1262 EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),
1188 static_cast<size_t>(max_len)); 1263 static_cast<size_t>(max_len));
1189 1264
@@ -1255,14 +1330,14 @@ TEST(liblog, dual_reader) {
1255 android_logger_list_close(logger_list1); 1330 android_logger_list_close(logger_list1);
1256 android_logger_list_close(logger_list2); 1331 android_logger_list_close(logger_list2);
1257 1332
1258 EXPECT_EQ(num, count1); 1333 EXPECT_EQ(num * SUPPORTS_END_TO_END, count1);
1259 EXPECT_EQ(num - 10, count2); 1334 EXPECT_EQ((num - 10) * SUPPORTS_END_TO_END, count2);
1260#else 1335#else
1261 GTEST_LOG_(INFO) << "This test does nothing.\n"; 1336 GTEST_LOG_(INFO) << "This test does nothing.\n";
1262#endif 1337#endif
1263} 1338}
1264 1339
1265#ifndef USING_LOGGER_LOCAL // Do not retest logprint 1340#ifdef USING_LOGGER_DEFAULT // Do not retest logprint
1266static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) { 1341static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {
1267 return android_log_shouldPrintLine(p_format, tag, pri) 1342 return android_log_shouldPrintLine(p_format, tag, pri)
1268 && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1)); 1343 && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));
@@ -1331,9 +1406,9 @@ TEST(liblog, filterRule) {
1331 1406
1332 android_log_format_free(p_format); 1407 android_log_format_free(p_format);
1333} 1408}
1334#endif // !USING_LOGGER_LOCAL 1409#endif // USING_LOGGER_DEFAULT
1335 1410
1336#ifndef USING_LOGGER_LOCAL // Do not retest property handling 1411#ifdef USING_LOGGER_DEFAULT // Do not retest property handling
1337TEST(liblog, is_loggable) { 1412TEST(liblog, is_loggable) {
1338#ifdef __ANDROID__ 1413#ifdef __ANDROID__
1339 static const char tag[] = "is_loggable"; 1414 static const char tag[] = "is_loggable";
@@ -1632,12 +1707,12 @@ TEST(liblog, is_loggable) {
1632 GTEST_LOG_(INFO) << "This test does nothing.\n"; 1707 GTEST_LOG_(INFO) << "This test does nothing.\n";
1633#endif 1708#endif
1634} 1709}
1635#endif // !USING_LOGGER_LOCAL 1710#endif // USING_LOGGER_DEFAULT
1636 1711
1637// Following tests the specific issues surrounding error handling wrt logd. 1712// Following tests the specific issues surrounding error handling wrt logd.
1638// Kills logd and toss all collected data, equivalent to logcat -b all -c, 1713// Kills logd and toss all collected data, equivalent to logcat -b all -c,
1639// except we also return errors to the logging callers. 1714// except we also return errors to the logging callers.
1640#ifndef USING_LOGGER_LOCAL 1715#ifdef USING_LOGGER_DEFAULT
1641#ifdef TEST_PREFIX 1716#ifdef TEST_PREFIX
1642// helper to liblog.enoent to count end-to-end matching logging messages. 1717// helper to liblog.enoent to count end-to-end matching logging messages.
1643static int count_matching_ts(log_time ts) { 1718static int count_matching_ts(log_time ts) {
@@ -1687,7 +1762,7 @@ TEST(liblog, enoent) {
1687 TEST_PREFIX 1762 TEST_PREFIX
1688 log_time ts(CLOCK_MONOTONIC); 1763 log_time ts(CLOCK_MONOTONIC);
1689 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); 1764 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
1690 EXPECT_EQ(1, count_matching_ts(ts)); 1765 EXPECT_EQ(SUPPORTS_END_TO_END, count_matching_ts(ts));
1691 1766
1692 // This call will fail if we are setuid(AID_SYSTEM), beware of any 1767 // This call will fail if we are setuid(AID_SYSTEM), beware of any
1693 // test prior to this one playing with setuid and causing interference. 1768 // test prior to this one playing with setuid and causing interference.
@@ -1732,18 +1807,18 @@ TEST(liblog, enoent) {
1732 1807
1733 ts = log_time(CLOCK_MONOTONIC); 1808 ts = log_time(CLOCK_MONOTONIC);
1734 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); 1809 EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
1735 EXPECT_EQ(1, count_matching_ts(ts)); 1810 EXPECT_EQ(SUPPORTS_END_TO_END, count_matching_ts(ts));
1736 1811
1737#else 1812#else
1738 GTEST_LOG_(INFO) << "This test does nothing.\n"; 1813 GTEST_LOG_(INFO) << "This test does nothing.\n";
1739#endif 1814#endif
1740} 1815}
1741#endif // !USING_LOCAL_LOGGER 1816#endif // USING_LOCAL_LOGD
1742 1817
1743// Below this point we run risks of setuid(AID_SYSTEM) which may affect others. 1818// Below this point we run risks of setuid(AID_SYSTEM) which may affect others.
1744 1819
1745// Do not retest properties, and cannot log into LOG_ID_SECURITY 1820// Do not retest properties, and cannot log into LOG_ID_SECURITY
1746#ifndef USING_LOGGER_LOCAL 1821#ifdef USING_LOGGER_DEFAULT
1747TEST(liblog, __security) { 1822TEST(liblog, __security) {
1748#ifdef __ANDROID__ 1823#ifdef __ANDROID__
1749 static const char persist_key[] = "persist.logd.security"; 1824 static const char persist_key[] = "persist.logd.security";
@@ -1929,7 +2004,7 @@ TEST(liblog, __security_buffer) {
1929 GTEST_LOG_(INFO) << "This test does nothing.\n"; 2004 GTEST_LOG_(INFO) << "This test does nothing.\n";
1930#endif 2005#endif
1931} 2006}
1932#endif // !USING_LOGGER_LOCAL 2007#endif // USING_LOGGER_DEFAULT
1933 2008
1934#ifdef TEST_PREFIX 2009#ifdef TEST_PREFIX
1935static void android_errorWriteWithInfoLog_helper(int TAG, const char* SUBTAG, 2010static void android_errorWriteWithInfoLog_helper(int TAG, const char* SUBTAG,
@@ -2047,7 +2122,7 @@ TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) {
2047 max_payload_buf, 2122 max_payload_buf,
2048 200, 2123 200,
2049 count); 2124 count);
2050 EXPECT_EQ(1, count); 2125 EXPECT_EQ(SUPPORTS_END_TO_END, count);
2051#else 2126#else
2052 GTEST_LOG_(INFO) << "This test does nothing.\n"; 2127 GTEST_LOG_(INFO) << "This test does nothing.\n";
2053#endif 2128#endif
@@ -2063,7 +2138,7 @@ TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__data_too_l
2063 max_payload_buf, 2138 max_payload_buf,
2064 sizeof(max_payload_buf), 2139 sizeof(max_payload_buf),
2065 count); 2140 count);
2066 EXPECT_EQ(1, count); 2141 EXPECT_EQ(SUPPORTS_END_TO_END, count);
2067#else 2142#else
2068 GTEST_LOG_(INFO) << "This test does nothing.\n"; 2143 GTEST_LOG_(INFO) << "This test does nothing.\n";
2069#endif 2144#endif
@@ -2095,7 +2170,7 @@ TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__subtag_too
2095 max_payload_buf, 2170 max_payload_buf,
2096 200, 2171 200,
2097 count); 2172 count);
2098 EXPECT_EQ(1, count); 2173 EXPECT_EQ(SUPPORTS_END_TO_END, count);
2099#else 2174#else
2100 GTEST_LOG_(INFO) << "This test does nothing.\n"; 2175 GTEST_LOG_(INFO) << "This test does nothing.\n";
2101#endif 2176#endif
@@ -2118,6 +2193,46 @@ static void android_errorWriteLog_helper(int TAG, const char *SUBTAG, int& count
2118 2193
2119 count = 0; 2194 count = 0;
2120 2195
2196 // Do a Before and After on the count to measure the effect. Decrement
2197 // what we find in Before to set the stage.
2198 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
2199 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
2200
2201 for (;;) {
2202 log_msg log_msg;
2203 if (android_logger_list_read(logger_list, &log_msg) <= 0) break;
2204
2205 char *eventData = log_msg.msg();
2206 if (!eventData) continue;
2207
2208 // Tag
2209 int tag = get4LE(eventData);
2210 eventData += 4;
2211
2212 if (tag != TAG) continue;
2213
2214 if (!SUBTAG) {
2215 // This tag should not have been written because the data was null
2216 --count;
2217 break;
2218 }
2219
2220 // List type
2221 eventData++;
2222 // Number of elements in list
2223 eventData++;
2224 // Element #1: string type for subtag
2225 eventData++;
2226
2227 eventData +=4;
2228
2229 if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) continue;
2230 --count;
2231 }
2232
2233 android_logger_list_close(logger_list);
2234
2235 // Do an After on the count to measure the effect.
2121 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( 2236 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
2122 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); 2237 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
2123 2238
@@ -2184,7 +2299,7 @@ TEST(liblog, android_errorWriteLog__android_logger_list_read__success) {
2184#ifdef TEST_PREFIX 2299#ifdef TEST_PREFIX
2185 int count; 2300 int count;
2186 android_errorWriteLog_helper(123456785, "test-subtag", count); 2301 android_errorWriteLog_helper(123456785, "test-subtag", count);
2187 EXPECT_EQ(1, count); 2302 EXPECT_EQ(SUPPORTS_END_TO_END, count);
2188#else 2303#else
2189 GTEST_LOG_(INFO) << "This test does nothing.\n"; 2304 GTEST_LOG_(INFO) << "This test does nothing.\n";
2190#endif 2305#endif
@@ -2703,7 +2818,7 @@ static void create_android_logger(const char *(*fn)(uint32_t tag, size_t &expect
2703 EXPECT_EQ(0, strcmp(expected_string, msgBuf)); 2818 EXPECT_EQ(0, strcmp(expected_string, msgBuf));
2704 } 2819 }
2705 2820
2706 EXPECT_EQ(1, count); 2821 EXPECT_EQ(SUPPORTS_END_TO_END, count);
2707 2822
2708 android_logger_list_close(logger_list); 2823 android_logger_list_close(logger_list);
2709} 2824}
@@ -2789,7 +2904,7 @@ TEST(liblog, create_android_logger_android_log_error_write_null) {
2789#endif 2904#endif
2790} 2905}
2791 2906
2792#ifndef USING_LOGGER_LOCAL // Do not retest logger list handling 2907#ifdef USING_LOGGER_DEFAULT // Do not retest logger list handling
2793TEST(liblog, create_android_logger_overflow) { 2908TEST(liblog, create_android_logger_overflow) {
2794 android_log_context ctx; 2909 android_log_context ctx;
2795 2910
@@ -2829,9 +2944,9 @@ TEST(liblog, android_log_write_list_buffer) {
2829 msgBuf, sizeof(msgBuf)), 0); 2944 msgBuf, sizeof(msgBuf)), 0);
2830 EXPECT_STREQ(msgBuf, "[1005,tag_def,(tag|1),(name|3),(format|3)]"); 2945 EXPECT_STREQ(msgBuf, "[1005,tag_def,(tag|1),(name|3),(format|3)]");
2831} 2946}
2832#endif // !USING_LOGGER_LOCAL 2947#endif // USING_LOGGER_DEFAULT
2833 2948
2834#ifndef USING_LOGGER_LOCAL // Do not retest pmsg functionality 2949#ifdef USING_LOGGER_DEFAULT // Do not retest pmsg functionality
2835#ifdef __ANDROID__ 2950#ifdef __ANDROID__
2836static const char __pmsg_file[] = 2951static const char __pmsg_file[] =
2837 "/data/william-shakespeare/MuchAdoAboutNothing.txt"; 2952 "/data/william-shakespeare/MuchAdoAboutNothing.txt";
@@ -2957,9 +3072,9 @@ TEST(liblog, __android_log_pmsg_file_read) {
2957 GTEST_LOG_(INFO) << "This test does nothing.\n"; 3072 GTEST_LOG_(INFO) << "This test does nothing.\n";
2958#endif 3073#endif
2959} 3074}
2960#endif // !USING_LOGGER_LOCAL 3075#endif // USING_LOGGER_DEFAULT
2961 3076
2962#ifndef USING_LOGGER_LOCAL // Do not retest event mapping functionality 3077#ifdef USING_LOGGER_DEFAULT // Do not retest event mapping functionality
2963#ifdef __ANDROID__ 3078#ifdef __ANDROID__
2964// must be: '<needle:> 0 kB' 3079// must be: '<needle:> 0 kB'
2965static bool isZero(const std::string &content, std::string::size_type pos, 3080static bool isZero(const std::string &content, std::string::size_type pos,
@@ -3063,9 +3178,9 @@ TEST(liblog, event_log_tags) {
3063 GTEST_LOG_(INFO) << "This test does nothing.\n"; 3178 GTEST_LOG_(INFO) << "This test does nothing.\n";
3064#endif 3179#endif
3065} 3180}
3066#endif // !USING_LOGGER_LOCAL 3181#endif // USING_LOGGER_DEFAULT
3067 3182
3068#ifndef USING_LOGGER_LOCAL // Do not retest ratelimit 3183#ifdef USING_LOGGER_DEFAULT // Do not retest ratelimit
3069TEST(liblog, __android_log_ratelimit) { 3184TEST(liblog, __android_log_ratelimit) {
3070 time_t state = 0; 3185 time_t state = 0;
3071 3186
@@ -3097,9 +3212,9 @@ TEST(liblog, __android_log_ratelimit) {
3097 } 3212 }
3098 // Do not test default seconds, to allow liblog to tune freely 3213 // Do not test default seconds, to allow liblog to tune freely
3099} 3214}
3100#endif // !USING_LOGGER_LOCAL 3215#endif // USING_LOGGER_DEFAULT
3101 3216
3102#ifndef USING_LOGGER_LOCAL // Do not retest event mapping functionality 3217#ifdef USING_LOGGER_DEFAULT // Do not retest event mapping functionality
3103TEST(liblog, android_lookupEventTagNum) { 3218TEST(liblog, android_lookupEventTagNum) {
3104#ifdef __ANDROID__ 3219#ifdef __ANDROID__
3105 EventTagMap* map = android_openEventTagMap(NULL); 3220 EventTagMap* map = android_openEventTagMap(NULL);
@@ -3115,4 +3230,4 @@ TEST(liblog, android_lookupEventTagNum) {
3115 GTEST_LOG_(INFO) << "This test does nothing.\n"; 3230 GTEST_LOG_(INFO) << "This test does nothing.\n";
3116#endif 3231#endif
3117} 3232}
3118#endif // !USING_LOGGER_LOCAL 3233#endif // USING_LOGGER_DEFAULT
diff --git a/liblog/tests/liblog_test_stderr.cpp b/liblog/tests/liblog_test_stderr.cpp
new file mode 100644
index 000000000..f0cb192d7
--- /dev/null
+++ b/liblog/tests/liblog_test_stderr.cpp
@@ -0,0 +1,5 @@
1#include <log/log_frontend.h>
2#define liblog liblog_stderr
3#define TEST_PREFIX android_set_log_frontend(LOGGER_STDERR);
4#define USING_LOGGER_STDERR
5#include "liblog_test.cpp"
diff --git a/liblog/tests/liblog_test_stderr_local.cpp b/liblog/tests/liblog_test_stderr_local.cpp
new file mode 100644
index 000000000..1555b4e00
--- /dev/null
+++ b/liblog/tests/liblog_test_stderr_local.cpp
@@ -0,0 +1,4 @@
1#include <log/log_frontend.h>
2#define liblog liblog_stderr_local
3#define TEST_PREFIX android_set_log_frontend(LOGGER_LOCAL | LOGGER_STDERR);
4#include "liblog_test.cpp"