diff options
Diffstat (limited to 'liblog')
-rw-r--r-- | liblog/Android.mk | 4 | ||||
-rw-r--r-- | liblog/log_read.c | 50 | ||||
-rw-r--r-- | liblog/log_read_kern.c | 11 | ||||
-rw-r--r-- | liblog/logd_write.c | 56 | ||||
-rw-r--r-- | liblog/logd_write_kern.c | 11 | ||||
-rw-r--r-- | liblog/logprint.c | 85 | ||||
-rw-r--r-- | liblog/tests/Android.mk | 18 | ||||
-rw-r--r-- | liblog/tests/libc_test.cpp | 138 | ||||
-rw-r--r-- | liblog/tests/liblog_test.cpp | 129 |
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); +} |