summaryrefslogtreecommitdiffstats
path: root/liblog
diff options
context:
space:
mode:
Diffstat (limited to 'liblog')
-rw-r--r--liblog/Android.mk4
-rw-r--r--liblog/log_read.c50
-rw-r--r--liblog/log_read_kern.c11
-rw-r--r--liblog/logd_write.c56
-rw-r--r--liblog/logd_write_kern.c11
-rw-r--r--liblog/logprint.c85
-rw-r--r--liblog/tests/Android.mk18
-rw-r--r--liblog/tests/libc_test.cpp138
-rw-r--r--liblog/tests/liblog_test.cpp129
9 files changed, 371 insertions, 131 deletions
diff --git a/liblog/Android.mk b/liblog/Android.mk
index a23de2d..5e01903 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -22,10 +22,6 @@ else
liblog_sources := logd_write_kern.c
endif
-ifneq ($(filter userdebug eng,$(TARGET_BUILD_VARIANT)),)
-liblog_cflags := -DUSERDEBUG_BUILD=1
-endif
-
# some files must not be compiled when building against Mingw
# they correspond to features not used by our host development tools
# which are also hard or even impossible to port to native Win32
diff --git a/liblog/log_read.c b/liblog/log_read.c
index 2dd07e6..11fe848 100644
--- a/liblog/log_read.c
+++ b/liblog/log_read.c
@@ -17,6 +17,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <poll.h>
#include <signal.h>
#include <stddef.h>
#define NOMINMAX /* for windows to suppress definition of min in stdlib.h */
@@ -196,7 +197,8 @@ static const char *LOG_NAME[LOG_ID_MAX] = {
[LOG_ID_MAIN] = "main",
[LOG_ID_RADIO] = "radio",
[LOG_ID_EVENTS] = "events",
- [LOG_ID_SYSTEM] = "system"
+ [LOG_ID_SYSTEM] = "system",
+ [LOG_ID_CRASH] = "crash",
};
const char *android_log_id_to_name(log_id_t log_id)
@@ -272,6 +274,8 @@ static ssize_t send_log_msg(struct logger *logger,
const char *msg, char *buf, size_t buf_size)
{
ssize_t ret;
+ size_t len;
+ char *cp;
int errno_save = 0;
int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM);
@@ -283,12 +287,44 @@ static ssize_t send_log_msg(struct logger *logger,
snprintf(buf, buf_size, msg, logger ? logger->id : (unsigned) -1);
}
- ret = write(sock, buf, strlen(buf) + 1);
+ len = strlen(buf) + 1;
+ ret = TEMP_FAILURE_RETRY(write(sock, buf, len));
if (ret <= 0) {
goto done;
}
- ret = read(sock, buf, buf_size);
+ len = buf_size;
+ cp = buf;
+ while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {
+ struct pollfd p;
+
+ if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {
+ break;
+ }
+
+ len -= ret;
+ cp += ret;
+
+ memset(&p, 0, sizeof(p));
+ p.fd = sock;
+ p.events = POLLIN;
+
+ /* Give other side 20ms to refill pipe */
+ ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));
+
+ if (ret <= 0) {
+ break;
+ }
+
+ if (!(p.revents & POLLIN)) {
+ ret = 0;
+ break;
+ }
+ }
+
+ if (ret >= 0) {
+ ret += buf_size - len;
+ }
done:
if ((ret == -1) && errno) {
@@ -340,8 +376,6 @@ long android_logger_get_log_size(struct logger *logger)
return atol(buf);
}
-#ifdef USERDEBUG_BUILD
-
int android_logger_set_log_size(struct logger *logger, unsigned long size)
{
char buf[512];
@@ -352,8 +386,6 @@ int android_logger_set_log_size(struct logger *logger, unsigned long size)
return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));
}
-#endif /* USERDEBUG_BUILD */
-
/*
* returns the readable size of the log's ring buffer (that is, amount of the
* log consumed)
@@ -408,8 +440,6 @@ ssize_t android_logger_get_statistics(struct logger_list *logger_list,
return send_log_msg(NULL, NULL, buf, len);
}
-#ifdef USERDEBUG_BUILD
-
ssize_t android_logger_get_prune_list(struct logger_list *logger_list UNUSED,
char *buf, size_t len)
{
@@ -432,8 +462,6 @@ int android_logger_set_prune_list(struct logger_list *logger_list UNUSED,
return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));
}
-#endif /* USERDEBUG_BUILD */
-
struct logger_list *android_logger_list_alloc(int mode,
unsigned int tail,
pid_t pid)
diff --git a/liblog/log_read_kern.c b/liblog/log_read_kern.c
index 9cccb1d..021fe47 100644
--- a/liblog/log_read_kern.c
+++ b/liblog/log_read_kern.c
@@ -58,7 +58,8 @@ static const char *LOG_NAME[LOG_ID_MAX] = {
[LOG_ID_MAIN] = "main",
[LOG_ID_RADIO] = "radio",
[LOG_ID_EVENTS] = "events",
- [LOG_ID_SYSTEM] = "system"
+ [LOG_ID_SYSTEM] = "system",
+ [LOG_ID_CRASH] = "crash"
};
const char *android_log_id_to_name(log_id_t log_id)
@@ -232,16 +233,12 @@ long android_logger_get_log_size(struct logger *logger)
return logger_ioctl(logger, LOGGER_GET_LOG_BUF_SIZE, O_RDWR);
}
-#ifdef USERDEBUG_BUILD
-
int android_logger_set_log_size(struct logger *logger UNUSED,
unsigned long size UNUSED)
{
return -ENOTSUP;
}
-#endif /* USERDEBUG_BUILD */
-
/*
* returns the readable size of the log's ring buffer (that is, amount of the
* log consumed)
@@ -272,8 +269,6 @@ ssize_t android_logger_get_statistics(struct logger_list *logger_list UNUSED,
return -ENOTSUP;
}
-#ifdef USERDEBUG_BUILD
-
ssize_t android_logger_get_prune_list(struct logger_list *logger_list UNUSED,
char *buf, size_t len)
{
@@ -289,8 +284,6 @@ int android_logger_set_prune_list(struct logger_list *logger_list UNUSED,
return -ENOTSUP;
}
-#endif /* USERDEBUG_BUILD */
-
struct logger_list *android_logger_list_alloc(int mode,
unsigned int tail,
pid_t pid)
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index 9c73dad..bd36a65 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -54,7 +54,7 @@ static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
static int logd_fd = -1;
#if FAKE_LOG_DEVICE
#define WEAK __attribute__((weak))
-static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
+static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1 };
#endif
/*
@@ -146,9 +146,15 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr)
ret = -errno;
}
} while (ret == -EINTR);
-
- return ret;
#else
+ static const unsigned header_length = 3;
+ struct iovec newVec[nr + header_length];
+ typeof_log_id_t log_id_buf;
+ uint16_t tid;
+ struct timespec ts;
+ log_time realtime_ts;
+ size_t i, payload_size;
+
if (getuid() == AID_LOGD) {
/*
* ignore log messages we send to ourself.
@@ -181,29 +187,33 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr)
* };
* };
*/
- static const unsigned header_length = 3;
- struct iovec newVec[nr + header_length];
- typeof_log_id_t log_id_buf = log_id;
- uint16_t tid = gettid();
+
+ log_id_buf = log_id;
+ tid = gettid();
newVec[0].iov_base = (unsigned char *) &log_id_buf;
newVec[0].iov_len = sizeof_log_id_t;
newVec[1].iov_base = (unsigned char *) &tid;
newVec[1].iov_len = sizeof(tid);
- struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
- log_time realtime_ts;
realtime_ts.tv_sec = ts.tv_sec;
realtime_ts.tv_nsec = ts.tv_nsec;
newVec[2].iov_base = (unsigned char *) &realtime_ts;
newVec[2].iov_len = sizeof(log_time);
- size_t i;
- for (i = header_length; i < nr + header_length; i++) {
- newVec[i].iov_base = vec[i-header_length].iov_base;
- newVec[i].iov_len = vec[i-header_length].iov_len;
+ for (payload_size = 0, i = header_length; i < nr + header_length; i++) {
+ newVec[i].iov_base = vec[i - header_length].iov_base;
+ payload_size += newVec[i].iov_len = vec[i - header_length].iov_len;
+
+ if (payload_size > LOGGER_ENTRY_MAX_PAYLOAD) {
+ newVec[i].iov_len -= payload_size - LOGGER_ENTRY_MAX_PAYLOAD;
+ if (newVec[i].iov_len) {
+ ++i;
+ }
+ break;
+ }
}
/*
@@ -212,7 +222,7 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr)
* ENOTCONN occurs if logd dies.
* EAGAIN occurs if logd is overloaded.
*/
- ret = writev(logd_fd, newVec, nr + header_length);
+ ret = writev(logd_fd, newVec, i);
if (ret < 0) {
ret = -errno;
if (ret == -ENOTCONN) {
@@ -234,8 +244,13 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr)
}
}
}
- return ret;
+
+ if (ret > (ssize_t)(sizeof_log_id_t + sizeof(tid) + sizeof(log_time))) {
+ ret -= sizeof_log_id_t + sizeof(tid) + sizeof(log_time);
+ }
#endif
+
+ return ret;
}
#if FAKE_LOG_DEVICE
@@ -243,7 +258,8 @@ static const char *LOG_NAME[LOG_ID_MAX] = {
[LOG_ID_MAIN] = "main",
[LOG_ID_RADIO] = "radio",
[LOG_ID_EVENTS] = "events",
- [LOG_ID_SYSTEM] = "system"
+ [LOG_ID_SYSTEM] = "system",
+ [LOG_ID_CRASH] = "crash"
};
const WEAK char *android_log_id_to_name(log_id_t log_id)
@@ -406,9 +422,15 @@ void __android_log_assert(const char *cond, const char *tag,
strcpy(buf, "Unspecified assertion failed");
}
+#if __BIONIC__
+ // Ensure debuggerd gets to see what went wrong by keeping the C library in the loop.
+ extern __noreturn void __android_fatal(const char* tag, const char* format, ...) __printflike(2, 3);
+ __android_fatal(tag ? tag : "", "%s", buf);
+#else
__android_log_write(ANDROID_LOG_FATAL, tag, buf);
-
__builtin_trap(); /* trap so we have a chance to debug the situation */
+#endif
+ /* NOTREACHED */
}
int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
diff --git a/liblog/logd_write_kern.c b/liblog/logd_write_kern.c
index 5ef349b..8c707ad 100644
--- a/liblog/logd_write_kern.c
+++ b/liblog/logd_write_kern.c
@@ -93,6 +93,9 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr)
int log_fd;
if (/*(int)log_id >= 0 &&*/ (int)log_id < (int)LOG_ID_MAX) {
+ if (log_id == LOG_ID_CRASH) {
+ log_id = LOG_ID_MAIN;
+ }
log_fd = log_fds[(int)log_id];
} else {
return -EBADF;
@@ -269,9 +272,15 @@ void __android_log_assert(const char *cond, const char *tag,
strcpy(buf, "Unspecified assertion failed");
}
+#if __BIONIC__
+ // Ensure debuggerd gets to see what went wrong by keeping the C library in the loop.
+ extern __noreturn void __android_fatal(const char* tag, const char* format, ...) __printflike(2, 3);
+ __android_fatal(tag ? tag : "", "%s", buf);
+#else
__android_log_write(ANDROID_LOG_FATAL, tag, buf);
-
__builtin_trap(); /* trap so we have a chance to debug the situation */
+#endif
+ /* NOTREACHED */
}
int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
diff --git a/liblog/logprint.c b/liblog/logprint.c
index a7480d5..3bc9f5a 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -938,88 +938,3 @@ done:
return ret;
}
-
-
-
-void logprint_run_tests()
-{
-#if 0
-
- fprintf(stderr, "tests disabled\n");
-
-#else
-
- int err;
- const char *tag;
- AndroidLogFormat *p_format;
-
- p_format = android_log_format_new();
-
- fprintf(stderr, "running tests\n");
-
- tag = "random";
-
- android_log_addFilterRule(p_format,"*:i");
-
- assert (ANDROID_LOG_INFO == filterPriForTag(p_format, "random"));
- assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
- android_log_addFilterRule(p_format, "*");
- assert (ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));
- assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
- android_log_addFilterRule(p_format, "*:v");
- assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));
- assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
- android_log_addFilterRule(p_format, "*:i");
- assert (ANDROID_LOG_INFO == filterPriForTag(p_format, "random"));
- assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
-
- android_log_addFilterRule(p_format, "random");
- assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));
- assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
- android_log_addFilterRule(p_format, "random:v");
- assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random"));
- assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
- android_log_addFilterRule(p_format, "random:d");
- assert (ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));
- assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
- android_log_addFilterRule(p_format, "random:w");
- assert (ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));
- assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
-
- android_log_addFilterRule(p_format, "crap:*");
- assert (ANDROID_LOG_VERBOSE== filterPriForTag(p_format, "crap"));
- assert(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
-
- // invalid expression
- err = android_log_addFilterRule(p_format, "random:z");
- assert (err < 0);
- assert (ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));
- assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
-
- // Issue #550946
- err = android_log_addFilterString(p_format, " ");
- assert(err == 0);
- assert(ANDROID_LOG_WARN == filterPriForTag(p_format, "random"));
-
- // note trailing space
- err = android_log_addFilterString(p_format, "*:s random:d ");
- assert(err == 0);
- assert(ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random"));
-
- err = android_log_addFilterString(p_format, "*:s random:z");
- assert(err < 0);
-
-
-#if 0
- char *ret;
- char defaultBuffer[512];
-
- ret = android_log_formatLogLine(p_format,
- defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
- 123, 123, "random", "nofile", strlen("Hello"), "Hello", NULL);
-#endif
-
-
- fprintf(stderr, "tests complete\n");
-#endif
-}
diff --git a/liblog/tests/Android.mk b/liblog/tests/Android.mk
index db06cf7..d1d9115 100644
--- a/liblog/tests/Android.mk
+++ b/liblog/tests/Android.mk
@@ -32,7 +32,7 @@ benchmark_c_flags := \
benchmark_src_files := \
benchmark_main.cpp \
- liblog_benchmark.cpp \
+ liblog_benchmark.cpp
# Build benchmarks for the device. Run with:
# adb shell liblog-benchmarks
@@ -59,10 +59,22 @@ test_c_flags := \
-g \
-Wall -Wextra \
-Werror \
- -fno-builtin \
+ -fno-builtin
test_src_files := \
- liblog_test.cpp \
+ liblog_test.cpp
+
+# to prevent breaking the build if bionic not relatively visible to us
+ifneq ($(wildcard $(LOCAL_PATH)/../../../../bionic/libc/bionic/libc_logging.cpp),)
+
+test_src_files += \
+ libc_test.cpp
+
+ifndef ($(TARGET_USES_LOGD),false)
+test_c_flags += -DTARGET_USES_LOGD
+endif
+
+endif
# Build tests for the device (with .so). Run with:
# adb shell /data/nativetest/liblog-unit-tests/liblog-unit-tests
diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp
new file mode 100644
index 0000000..0abc375
--- /dev/null
+++ b/liblog/tests/libc_test.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fcntl.h>
+#include <sys/cdefs.h>
+
+#include <gtest/gtest.h>
+
+// Should be in bionic test suite, *but* we are using liblog to confirm
+// end-to-end logging, so let the overly cute oedipus complex begin ...
+#include "../../../../bionic/libc/bionic/libc_logging.cpp" // not Standalone
+#define _ANDROID_LOG_H // Priorities redefined
+#define _LIBS_LOG_LOG_H // log ids redefined
+typedef unsigned char log_id_t; // log_id_t missing as a result
+#ifdef TARGET_USES_LOGD
+#define _LIBS_LOG_LOG_READ_H // log_time redefined
+#endif
+
+#include <log/log.h>
+#include <log/logger.h>
+#include <log/log_read.h>
+
+TEST(libc, __libc_android_log_event_int) {
+ struct logger_list *logger_list;
+
+ pid_t pid = getpid();
+
+ ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+ LOG_ID_EVENTS, O_RDONLY | O_NDELAY, 1000, pid)));
+
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ int value = ts.tv_nsec;
+
+ __libc_android_log_event_int(0, value);
+ usleep(1000000);
+
+ int count = 0;
+
+ for (;;) {
+ log_msg log_msg;
+ if (android_logger_list_read(logger_list, &log_msg) <= 0) {
+ break;
+ }
+
+ ASSERT_EQ(log_msg.entry.pid, pid);
+
+ if ((log_msg.entry.len != (4 + 1 + 4))
+ || ((int)log_msg.id() != LOG_ID_EVENTS)) {
+ continue;
+ }
+
+ char *eventData = log_msg.msg();
+
+ int incoming = (eventData[0] & 0xFF) |
+ ((eventData[1] & 0xFF) << 8) |
+ ((eventData[2] & 0xFF) << 16) |
+ ((eventData[3] & 0xFF) << 24);
+
+ if (incoming != 0) {
+ continue;
+ }
+
+ if (eventData[4] != EVENT_TYPE_INT) {
+ continue;
+ }
+
+ incoming = (eventData[4 + 1 + 0] & 0xFF) |
+ ((eventData[4 + 1 + 1] & 0xFF) << 8) |
+ ((eventData[4 + 1 + 2] & 0xFF) << 16) |
+ ((eventData[4 + 1 + 3] & 0xFF) << 24);
+
+ if (incoming == value) {
+ ++count;
+ }
+ }
+
+ EXPECT_EQ(1, count);
+
+ android_logger_list_close(logger_list);
+}
+
+TEST(libc, __libc_fatal_no_abort) {
+ struct logger_list *logger_list;
+
+ pid_t pid = getpid();
+
+ ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+ (log_id_t)LOG_ID_MAIN, O_RDONLY | O_NDELAY, 1000, pid)));
+
+ char b[80];
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ __libc_fatal_no_abort("%u.%09u", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec);
+ snprintf(b, sizeof(b),"%u.%09u", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec);
+ usleep(1000000);
+
+ int count = 0;
+
+ for (;;) {
+ log_msg log_msg;
+ if (android_logger_list_read(logger_list, &log_msg) <= 0) {
+ break;
+ }
+
+ ASSERT_EQ(log_msg.entry.pid, pid);
+
+ if ((int)log_msg.id() != LOG_ID_MAIN) {
+ continue;
+ }
+
+ char *data = log_msg.msg();
+
+ if ((*data == ANDROID_LOG_FATAL)
+ && !strcmp(data + 1, "libc")
+ && !strcmp(data + 1 + strlen(data + 1) + 1, b)) {
+ ++count;
+ }
+ }
+
+ EXPECT_EQ(1, count);
+
+ android_logger_list_close(logger_list);
+}
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index d726f2d..c6f981f 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -21,6 +21,7 @@
#include <log/log.h>
#include <log/logger.h>
#include <log/log_read.h>
+#include <log/logprint.h>
// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
// non-syscall libs. Since we are only using this in the emergency of
@@ -482,11 +483,68 @@ TEST(liblog, max_payload) {
}
}
+ android_logger_list_close(logger_list);
+
EXPECT_EQ(true, matches);
- EXPECT_LE(sizeof(max_payload_buf), max_len);
+ EXPECT_LE(sizeof(max_payload_buf), static_cast<size_t>(max_len));
+}
+
+TEST(liblog, too_big_payload) {
+ pid_t pid = getpid();
+ static const char big_payload_tag[] = "TEST_big_payload_XXXX";
+ char tag[sizeof(big_payload_tag)];
+ memcpy(tag, big_payload_tag, sizeof(tag));
+ snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
+
+ std::string longString(3266519, 'x');
+
+ ssize_t ret = LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM,
+ ANDROID_LOG_INFO, tag, longString.c_str()));
+
+ struct logger_list *logger_list;
+
+ ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+ LOG_ID_SYSTEM, O_RDONLY | O_NDELAY, 100, 0)));
+
+ ssize_t max_len = 0;
+
+ for(;;) {
+ log_msg log_msg;
+ if (android_logger_list_read(logger_list, &log_msg) <= 0) {
+ break;
+ }
+
+ if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
+ continue;
+ }
+
+ char *data = log_msg.msg() + 1;
+
+ if (strcmp(data, tag)) {
+ continue;
+ }
+
+ data += strlen(data) + 1;
+
+ const char *left = data;
+ const char *right = longString.c_str();
+ while (*left && *right && (*left == *right)) {
+ ++left;
+ ++right;
+ }
+
+ if (max_len <= (left - data)) {
+ max_len = left - data + 1;
+ }
+ }
android_logger_list_close(logger_list);
+
+ EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),
+ static_cast<size_t>(max_len));
+
+ EXPECT_EQ(ret, max_len + sizeof(big_payload_tag));
}
TEST(liblog, dual_reader) {
@@ -555,3 +613,72 @@ TEST(liblog, android_logger_get_) {
android_logger_list_close(logger_list);
}
+
+static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {
+ return android_log_shouldPrintLine(p_format, tag, pri)
+ && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));
+}
+
+TEST(liblog, filterRule) {
+ static const char tag[] = "random";
+
+ AndroidLogFormat *p_format = android_log_format_new();
+
+ android_log_addFilterRule(p_format,"*:i");
+
+ EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
+ EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
+ android_log_addFilterRule(p_format, "*");
+ EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
+ EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
+ android_log_addFilterRule(p_format, "*:v");
+ EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
+ EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
+ android_log_addFilterRule(p_format, "*:i");
+ EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
+ EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
+
+ android_log_addFilterRule(p_format, tag);
+ EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
+ EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
+ android_log_addFilterRule(p_format, "random:v");
+ EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
+ EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
+ android_log_addFilterRule(p_format, "random:d");
+ EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
+ EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
+ android_log_addFilterRule(p_format, "random:w");
+ EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
+ EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
+
+ android_log_addFilterRule(p_format, "crap:*");
+ EXPECT_TRUE (checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE));
+ EXPECT_TRUE(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
+
+ // invalid expression
+ EXPECT_TRUE (android_log_addFilterRule(p_format, "random:z") < 0);
+ EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
+ EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
+
+ // Issue #550946
+ EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0);
+ EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
+
+ // note trailing space
+ EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0);
+ EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
+
+ EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0);
+
+#if 0 // bitrot, seek update
+ char defaultBuffer[512];
+
+ android_log_formatLogLine(p_format,
+ defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
+ 123, 123, tag, "nofile", strlen("Hello"), "Hello", NULL);
+
+ fprintf(stderr, "%s\n", defaultBuffer);
+#endif
+
+ android_log_format_free(p_format);
+}