diff options
Diffstat (limited to 'liblog')
-rw-r--r-- | liblog/Android.mk | 24 | ||||
-rw-r--r-- | liblog/event_tag_map.c | 28 | ||||
-rw-r--r-- | liblog/fake_log_device.c | 18 | ||||
-rw-r--r-- | liblog/log_read.c | 19 | ||||
-rw-r--r-- | liblog/log_read_kern.c | 21 | ||||
-rw-r--r-- | liblog/log_time.cpp | 4 | ||||
-rw-r--r-- | liblog/logd_write.c | 73 | ||||
-rw-r--r-- | liblog/logd_write_kern.c | 46 | ||||
-rw-r--r-- | liblog/logprint.c | 235 | ||||
-rw-r--r-- | liblog/tests/Android.mk | 10 | ||||
-rw-r--r-- | liblog/tests/benchmark_main.cpp | 1 | ||||
-rw-r--r-- | liblog/tests/libc_test.cpp | 4 | ||||
-rw-r--r-- | liblog/tests/liblog_benchmark.cpp | 4 | ||||
-rw-r--r-- | liblog/tests/liblog_test.cpp | 74 |
14 files changed, 300 insertions, 261 deletions
diff --git a/liblog/Android.mk b/liblog/Android.mk index 5e01903..a4e5f5e 100644 --- a/liblog/Android.mk +++ b/liblog/Android.mk @@ -57,11 +57,8 @@ endif # ======================================================== LOCAL_MODULE := liblog LOCAL_SRC_FILES := $(liblog_host_sources) -LOCAL_LDLIBS := -lpthread -ifeq ($(strip $(HOST_OS)),linux) -LOCAL_LDLIBS += -lrt -endif -LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 +LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 -Werror +LOCAL_MULTILIB := both include $(BUILD_HOST_STATIC_LIBRARY) include $(CLEAR_VARS) @@ -70,33 +67,22 @@ LOCAL_WHOLE_STATIC_LIBRARIES := liblog ifeq ($(strip $(HOST_OS)),linux) LOCAL_LDLIBS := -lrt endif +LOCAL_MULTILIB := both include $(BUILD_HOST_SHARED_LIBRARY) -# Static library for host, 64-bit -# ======================================================== -include $(CLEAR_VARS) -LOCAL_MODULE := lib64log -LOCAL_SRC_FILES := $(liblog_host_sources) -LOCAL_LDLIBS := -lpthread -ifeq ($(strip $(HOST_OS)),linux) -LOCAL_LDLIBS += -lrt -endif -LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 -m64 -include $(BUILD_HOST_STATIC_LIBRARY) - # Shared and static library for target # ======================================================== include $(CLEAR_VARS) LOCAL_MODULE := liblog LOCAL_SRC_FILES := $(liblog_target_sources) -LOCAL_CFLAGS := $(liblog_cflags) +LOCAL_CFLAGS := -Werror include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := liblog LOCAL_WHOLE_STATIC_LIBRARIES := liblog -LOCAL_CFLAGS := $(liblog_cflags) +LOCAL_CFLAGS := -Werror include $(BUILD_SHARED_LIBRARY) include $(call first-makefiles-under,$(LOCAL_PATH)) diff --git a/liblog/event_tag_map.c b/liblog/event_tag_map.c index f3d1e2f..bea99aa 100644 --- a/liblog/event_tag_map.c +++ b/liblog/event_tag_map.c @@ -13,15 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include <log/event_tag_map.h> -#include <log/log.h> +#include <assert.h> +#include <errno.h> +#include <fcntl.h> #include <stdlib.h> #include <string.h> -#include <fcntl.h> #include <sys/mman.h> -#include <errno.h> -#include <assert.h> + +#include <log/event_tag_map.h> +#include <log/log.h> #define OUT_TAG "EventTagMap" @@ -52,7 +53,6 @@ static int countMapLines(const EventTagMap* map); static int parseMapLines(EventTagMap* map); static int scanTagLine(char** pData, EventTag* tag, int lineNum); static int sortTags(EventTagMap* map); -static void dumpTags(const EventTagMap* map); /* @@ -185,8 +185,6 @@ static inline int isCharDigit(char c) */ static int processFile(EventTagMap* map) { - EventTag* tagArray = NULL; - /* get a tag count */ map->numTags = countMapLines(map); if (map->numTags < 0) @@ -422,17 +420,3 @@ static int sortTags(EventTagMap* map) return 0; } - -/* - * Dump the tag array for debugging. - */ -static void dumpTags(const EventTagMap* map) -{ - int i; - - for (i = 0; i < map->numTags; i++) { - const EventTag* tag = &map->tagArray[i]; - printf(" %3d: %6d '%s'\n", i, tag->tagIndex, tag->tagStr); - } -} - diff --git a/liblog/fake_log_device.c b/liblog/fake_log_device.c index da83a85..b8d87bb 100644 --- a/liblog/fake_log_device.c +++ b/liblog/fake_log_device.c @@ -21,18 +21,22 @@ */ #include "fake_log_device.h" -#include <log/logd.h> - -#include <stdlib.h> -#include <string.h> #include <ctype.h> #include <errno.h> #include <fcntl.h> +#include <stdlib.h> +#include <string.h> + +#include <log/logd.h> #ifdef HAVE_PTHREADS #include <pthread.h> #endif +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif + #define kMaxTagLen 16 /* from the long-dead utils/Log.cpp */ #define kTagSetSize 16 /* arbitrary */ @@ -348,7 +352,7 @@ static ssize_t fake_writev(int fd, const struct iovec *iov, int iovcnt) { static void showLog(LogState *state, int logPrio, const char* tag, const char* msg) { -#if defined(HAVE_LOCALTIME_R) +#if !defined(_WIN32) struct tm tmBuf; #endif struct tm* ptm; @@ -373,7 +377,7 @@ static void showLog(LogState *state, * in the time stamp. Don't use forward slashes, parenthesis, * brackets, asterisks, or other special chars here. */ -#if defined(HAVE_LOCALTIME_R) +#if !defined(_WIN32) ptm = localtime_r(&when, &tmBuf); #else ptm = localtime(&when); @@ -613,7 +617,7 @@ static int logClose(int fd) /* * Open a log output device and return a fake fd. */ -static int logOpen(const char* pathName, int flags) +static int logOpen(const char* pathName, int flags __unused) { LogState *logState; int fd = -1; diff --git a/liblog/log_read.c b/liblog/log_read.c index 11fe848..ca5a1a7 100644 --- a/liblog/log_read.c +++ b/liblog/log_read.c @@ -23,6 +23,7 @@ #define NOMINMAX /* for windows to suppress definition of min in stdlib.h */ #include <stdlib.h> #include <string.h> +#include <sys/cdefs.h> #include <unistd.h> #include <cutils/list.h> @@ -34,7 +35,9 @@ #define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y)))) #define WEAK __attribute__((weak)) -#define UNUSED __attribute__((unused)) +#ifndef __unused +#define __unused __attribute__((unused)) +#endif /* Private copy of ../libcutils/socket_local_client.c prevent library loops */ @@ -142,11 +145,10 @@ error: * Used by AndroidSocketImpl */ int WEAK socket_local_client_connect(int fd, const char *name, int namespaceId, - int type UNUSED) + int type __unused) { struct sockaddr_un addr; socklen_t alen; - size_t namelen; int err; err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen); @@ -409,7 +411,7 @@ long android_logger_get_log_readable_size(struct logger *logger) /* * returns the logger version */ -int android_logger_get_log_version(struct logger *logger UNUSED) +int android_logger_get_log_version(struct logger *logger __unused) { return 3; } @@ -420,7 +422,6 @@ int android_logger_get_log_version(struct logger *logger UNUSED) ssize_t android_logger_get_statistics(struct logger_list *logger_list, char *buf, size_t len) { - struct listnode *node; struct logger *logger; char *cp = buf; size_t remaining = len; @@ -440,13 +441,13 @@ ssize_t android_logger_get_statistics(struct logger_list *logger_list, return send_log_msg(NULL, NULL, buf, len); } -ssize_t android_logger_get_prune_list(struct logger_list *logger_list UNUSED, +ssize_t android_logger_get_prune_list(struct logger_list *logger_list __unused, char *buf, size_t len) { return send_log_msg(NULL, "getPruneList", buf, len); } -int android_logger_set_prune_list(struct logger_list *logger_list UNUSED, +int android_logger_set_prune_list(struct logger_list *logger_list __unused, char *buf, size_t len) { const char cmd[] = "setPruneList "; @@ -512,9 +513,7 @@ struct logger_list *android_logger_list_alloc_time(int mode, struct logger *android_logger_open(struct logger_list *logger_list, log_id_t id) { - struct listnode *node; struct logger *logger; - char *n; if (!logger_list || (id >= LOG_ID_MAX)) { goto err; @@ -561,7 +560,7 @@ struct logger_list *android_logger_list_open(log_id_t id, return logger_list; } -static void caught_signal(int signum UNUSED) +static void caught_signal(int signum __unused) { } diff --git a/liblog/log_read_kern.c b/liblog/log_read_kern.c index 021fe47..41b8a51 100644 --- a/liblog/log_read_kern.c +++ b/liblog/log_read_kern.c @@ -21,12 +21,13 @@ #include <string.h> #include <stdio.h> #include <stdlib.h> +#include <sys/cdefs.h> +#include <sys/ioctl.h> + #include <cutils/list.h> #include <log/log.h> #include <log/logger.h> -#include <sys/ioctl.h> - #define __LOGGERIO 0xAE #define LOGGER_GET_LOG_BUF_SIZE _IO(__LOGGERIO, 1) /* size of log */ @@ -51,7 +52,9 @@ typedef char bool; logger != node_to_item(&(logger_list)->node, struct logger, node); \ logger = node_to_item((logger)->node.next, struct logger, node)) -#define UNUSED __attribute__((unused)) +#ifndef __unused +#define __unused __attribute__((unused)) +#endif /* In the future, we would like to make this list extensible */ static const char *LOG_NAME[LOG_ID_MAX] = { @@ -233,8 +236,8 @@ long android_logger_get_log_size(struct logger *logger) return logger_ioctl(logger, LOGGER_GET_LOG_BUF_SIZE, O_RDWR); } -int android_logger_set_log_size(struct logger *logger UNUSED, - unsigned long size UNUSED) +int android_logger_set_log_size(struct logger *logger __unused, + unsigned long size __unused) { return -ENOTSUP; } @@ -262,21 +265,21 @@ int android_logger_get_log_version(struct logger *logger) */ static const char unsupported[] = "18\nNot Supported\n\f"; -ssize_t android_logger_get_statistics(struct logger_list *logger_list UNUSED, +ssize_t android_logger_get_statistics(struct logger_list *logger_list __unused, char *buf, size_t len) { strncpy(buf, unsupported, len); return -ENOTSUP; } -ssize_t android_logger_get_prune_list(struct logger_list *logger_list UNUSED, +ssize_t android_logger_get_prune_list(struct logger_list *logger_list __unused, char *buf, size_t len) { strncpy(buf, unsupported, len); return -ENOTSUP; } -int android_logger_set_prune_list(struct logger_list *logger_list UNUSED, +int android_logger_set_prune_list(struct logger_list *logger_list __unused, char *buf, size_t len) { static const char unsupported_error[] = "Unsupported"; @@ -302,7 +305,7 @@ struct logger_list *android_logger_list_alloc(int mode, } struct logger_list *android_logger_list_alloc_time(int mode, - log_time start UNUSED, + log_time start __unused, pid_t pid) { return android_logger_list_alloc(mode, 0, pid); diff --git a/liblog/log_time.cpp b/liblog/log_time.cpp index 755c2d9..209a9da 100644 --- a/liblog/log_time.cpp +++ b/liblog/log_time.cpp @@ -39,7 +39,7 @@ char *log_time::strptime(const char *s, const char *format) { #endif struct tm *ptm; -#if (defined(HAVE_LOCALTIME_R)) +#if !defined(_WIN32) struct tm tmBuf; ptm = localtime_r(&now, &tmBuf); #else @@ -78,7 +78,7 @@ char *log_time::strptime(const char *s, const char *format) { ++ret; } now = tv_sec; -#if (defined(HAVE_LOCALTIME_R)) +#if !defined(_WIN32) ptm = localtime_r(&now, &tmBuf); #else ptm = localtime(&now); diff --git a/liblog/logd_write.c b/liblog/logd_write.c index bd36a65..b2668ce 100644 --- a/liblog/logd_write.c +++ b/liblog/logd_write.c @@ -31,6 +31,10 @@ #include <time.h> #include <unistd.h> +#ifdef __BIONIC__ +#include <android/set_abort_message.h> +#endif + #include <log/logd.h> #include <log/logger.h> #include <log/log_read.h> @@ -49,12 +53,14 @@ static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_ static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER; #endif -#define UNUSED __attribute__((__unused__)) +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif -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, -1 }; +#else +static int logd_fd = -1; #endif /* @@ -77,12 +83,14 @@ int __android_log_dev_available(void) return (g_log_status == kLogAvailable); } +#if !FAKE_LOG_DEVICE /* give up, resources too limited */ -static int __write_to_log_null(log_id_t log_fd UNUSED, struct iovec *vec UNUSED, - size_t nr UNUSED) +static int __write_to_log_null(log_id_t log_fd __unused, struct iovec *vec __unused, + size_t nr __unused) { return -1; } +#endif /* log_init_lock assumed */ static int __write_to_log_initialize() @@ -102,7 +110,7 @@ static int __write_to_log_initialize() close(i); } - i = socket(PF_UNIX, SOCK_DGRAM, 0); + i = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (i < 0) { ret = -errno; write_to_log = __write_to_log_null; @@ -154,10 +162,14 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) struct timespec ts; log_time realtime_ts; size_t i, payload_size; + static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */ - if (getuid() == AID_LOGD) { + if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */ + last_uid = getuid(); + } + if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */ /* - * ignore log messages we send to ourself. + * ignore log messages we send to ourself (logd). * Such log messages are often generated by libraries we depend on * which use standard Android logging. */ @@ -188,6 +200,10 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) * }; */ + clock_gettime(CLOCK_REALTIME, &ts); + realtime_ts.tv_sec = ts.tv_sec; + realtime_ts.tv_nsec = ts.tv_nsec; + log_id_buf = log_id; tid = gettid(); @@ -195,11 +211,6 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) newVec[0].iov_len = sizeof_log_id_t; newVec[1].iov_base = (unsigned char *) &tid; newVec[1].iov_len = sizeof(tid); - - clock_gettime(CLOCK_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); @@ -262,7 +273,7 @@ static const char *LOG_NAME[LOG_ID_MAX] = { [LOG_ID_CRASH] = "crash" }; -const WEAK char *android_log_id_to_name(log_id_t log_id) +const char *android_log_id_to_name(log_id_t log_id) { if (log_id >= LOG_ID_MAX) { log_id = LOG_ID_MAIN; @@ -323,6 +334,12 @@ int __android_log_write(int prio, const char *tag, const char *msg) tag = tmp_tag; } +#if __BIONIC__ + if (prio == ANDROID_LOG_FATAL) { + android_set_abort_message(msg); + } +#endif + vec[0].iov_base = (unsigned char *) &prio; vec[0].iov_len = 1; vec[1].iov_base = (void *) tag; @@ -422,14 +439,8 @@ 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 */ } @@ -464,3 +475,25 @@ int __android_log_btwrite(int32_t tag, char type, const void *payload, return write_to_log(LOG_ID_EVENTS, vec, 3); } + +/* + * Like __android_log_bwrite, but used for writing strings to the + * event log. + */ +int __android_log_bswrite(int32_t tag, const char *payload) +{ + struct iovec vec[4]; + char type = EVENT_TYPE_STRING; + uint32_t len = strlen(payload); + + vec[0].iov_base = &tag; + vec[0].iov_len = sizeof(tag); + vec[1].iov_base = &type; + vec[1].iov_len = sizeof(type); + vec[2].iov_base = &len; + vec[2].iov_len = sizeof(len); + vec[3].iov_base = (void*)payload; + vec[3].iov_len = len; + + return write_to_log(LOG_ID_EVENTS, vec, 4); +} diff --git a/liblog/logd_write_kern.c b/liblog/logd_write_kern.c index 8c707ad..ae621cb 100644 --- a/liblog/logd_write_kern.c +++ b/liblog/logd_write_kern.c @@ -28,6 +28,10 @@ #include <time.h> #include <unistd.h> +#ifdef __BIONIC__ +#include <android/set_abort_message.h> +#endif + #include <log/log.h> #include <log/logd.h> #include <log/logger.h> @@ -57,7 +61,9 @@ static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_ static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER; #endif -#define UNUSED __attribute__((__unused__)) +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 }; @@ -81,8 +87,8 @@ int __android_log_dev_available(void) return (g_log_status == kLogAvailable); } -static int __write_to_log_null(log_id_t log_fd UNUSED, struct iovec *vec UNUSED, - size_t nr UNUSED) +static int __write_to_log_null(log_id_t log_fd __unused, struct iovec *vec __unused, + size_t nr __unused) { return -1; } @@ -173,6 +179,12 @@ int __android_log_write(int prio, const char *tag, const char *msg) tag = tmp_tag; } +#if __BIONIC__ + if (prio == ANDROID_LOG_FATAL) { + android_set_abort_message(msg); + } +#endif + vec[0].iov_base = (unsigned char *) &prio; vec[0].iov_len = 1; vec[1].iov_base = (void *) tag; @@ -272,14 +284,8 @@ 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 */ } @@ -314,3 +320,25 @@ int __android_log_btwrite(int32_t tag, char type, const void *payload, return write_to_log(LOG_ID_EVENTS, vec, 3); } + +/* + * Like __android_log_bwrite, but used for writing strings to the + * event log. + */ +int __android_log_bswrite(int32_t tag, const char *payload) +{ + struct iovec vec[4]; + char type = EVENT_TYPE_STRING; + uint32_t len = strlen(payload); + + vec[0].iov_base = &tag; + vec[0].iov_len = sizeof(tag); + vec[1].iov_base = &type; + vec[1].iov_len = sizeof(type); + vec[2].iov_base = &len; + vec[2].iov_len = sizeof(len); + vec[3].iov_base = (void*)payload; + vec[3].iov_len = len; + + return write_to_log(LOG_ID_EVENTS, vec, 4); +} diff --git a/liblog/logprint.c b/liblog/logprint.c index a7480d5..9b5a543 100644 --- a/liblog/logprint.c +++ b/liblog/logprint.c @@ -17,14 +17,16 @@ #define _GNU_SOURCE /* for asprintf */ +#include <arpa/inet.h> +#include <assert.h> #include <ctype.h> -#include <stdio.h> #include <errno.h> -#include <stdlib.h> +#include <stdbool.h> #include <stdint.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> -#include <assert.h> -#include <arpa/inet.h> +#include <sys/param.h> #include <log/logd.h> #include <log/logprint.h> @@ -39,8 +41,23 @@ struct AndroidLogFormat_t { android_LogPriority global_pri; FilterInfo *filters; AndroidLogPrintFormat format; + bool colored_output; }; +/* + * gnome-terminal color tags + * See http://misc.flogisoft.com/bash/tip_colors_and_formatting + * for ideas on how to set the forground color of the text for xterm. + * The color manipulation character stream is defined as: + * ESC [ 3 8 ; 5 ; <color#> m + */ +#define ANDROID_COLOR_BLUE 75 +#define ANDROID_COLOR_DEFAULT 231 +#define ANDROID_COLOR_GREEN 40 +#define ANDROID_COLOR_ORANGE 166 +#define ANDROID_COLOR_RED 196 +#define ANDROID_COLOR_YELLOW 226 + static FilterInfo * filterinfo_new(const char * tag, android_LogPriority pri) { FilterInfo *p_ret; @@ -52,15 +69,7 @@ static FilterInfo * filterinfo_new(const char * tag, android_LogPriority pri) return p_ret; } -static void filterinfo_free(FilterInfo *p_info) -{ - if (p_info == NULL) { - return; - } - - free(p_info->mTag); - p_info->mTag = NULL; -} +/* balance to above, filterinfo_free left unimplemented */ /* * Note: also accepts 0-9 priorities @@ -118,6 +127,23 @@ static char filterPriToChar (android_LogPriority pri) } } +static int colorFromPri (android_LogPriority pri) +{ + switch (pri) { + case ANDROID_LOG_VERBOSE: return ANDROID_COLOR_DEFAULT; + case ANDROID_LOG_DEBUG: return ANDROID_COLOR_BLUE; + case ANDROID_LOG_INFO: return ANDROID_COLOR_GREEN; + case ANDROID_LOG_WARN: return ANDROID_COLOR_ORANGE; + case ANDROID_LOG_ERROR: return ANDROID_COLOR_RED; + case ANDROID_LOG_FATAL: return ANDROID_COLOR_RED; + case ANDROID_LOG_SILENT: return ANDROID_COLOR_DEFAULT; + + case ANDROID_LOG_DEFAULT: + case ANDROID_LOG_UNKNOWN: + default: return ANDROID_COLOR_DEFAULT; + } +} + static android_LogPriority filterPriForTag( AndroidLogFormat *p_format, const char *tag) { @@ -139,23 +165,6 @@ static android_LogPriority filterPriForTag( return p_format->global_pri; } -/** for debugging */ -static void dumpFilters(AndroidLogFormat *p_format) -{ - FilterInfo *p_fi; - - for (p_fi = p_format->filters ; p_fi != NULL ; p_fi = p_fi->p_next) { - char cPri = filterPriToChar(p_fi->mPri); - if (p_fi->mPri == ANDROID_LOG_DEFAULT) { - cPri = filterPriToChar(p_format->global_pri); - } - fprintf(stderr,"%s:%c\n", p_fi->mTag, cPri); - } - - fprintf(stderr,"*:%c\n", filterPriToChar(p_format->global_pri)); - -} - /** * returns 1 if this log line should be printed based on its priority * and tag, and 0 if it should not @@ -174,6 +183,7 @@ AndroidLogFormat *android_log_format_new() p_ret->global_pri = ANDROID_LOG_VERBOSE; p_ret->format = FORMAT_BRIEF; + p_ret->colored_output = false; return p_ret; } @@ -199,7 +209,10 @@ void android_log_format_free(AndroidLogFormat *p_format) void android_log_setPrintFormat(AndroidLogFormat *p_format, AndroidLogPrintFormat format) { - p_format->format=format; + if (format == FORMAT_COLOR) + p_format->colored_output = true; + else + p_format->format = format; } /** @@ -217,6 +230,7 @@ AndroidLogPrintFormat android_log_formatFromString(const char * formatString) else if (strcmp(formatString, "time") == 0) format = FORMAT_TIME; else if (strcmp(formatString, "threadtime") == 0) format = FORMAT_THREADTIME; else if (strcmp(formatString, "long") == 0) format = FORMAT_LONG; + else if (strcmp(formatString, "color") == 0) format = FORMAT_COLOR; else format = FORMAT_OFF; return format; @@ -234,7 +248,6 @@ AndroidLogPrintFormat android_log_formatFromString(const char * formatString) int android_log_addFilterRule(AndroidLogFormat *p_format, const char *filterExpression) { - size_t i=0; size_t tagNameLength; android_LogPriority pri = ANDROID_LOG_DEFAULT; @@ -713,18 +726,19 @@ char *android_log_formatLogLine ( const AndroidLogEntry *entry, size_t *p_outLength) { -#if defined(HAVE_LOCALTIME_R) +#if !defined(_WIN32) struct tm tmBuf; #endif struct tm* ptm; char timeBuf[32]; - char headerBuf[128]; char prefixBuf[128], suffixBuf[128]; char priChar; int prefixSuffixIsHeaderFooter = 0; char * ret = NULL; priChar = filterPriToChar(entry->priority); + size_t prefixLen = 0, suffixLen = 0; + size_t len; /* * Get the current date/time in pretty form @@ -735,7 +749,7 @@ char *android_log_formatLogLine ( * in the time stamp. Don't use forward slashes, parenthesis, * brackets, asterisks, or other special chars here. */ -#if defined(HAVE_LOCALTIME_R) +#if !defined(_WIN32) ptm = localtime_r(&(entry->tv_sec), &tmBuf); #else ptm = localtime(&(entry->tv_sec)); @@ -746,78 +760,84 @@ char *android_log_formatLogLine ( /* * Construct a buffer containing the log header and log message. */ - size_t prefixLen, suffixLen; + if (p_format->colored_output) { + prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), "\x1B[38;5;%dm", + colorFromPri(entry->priority)); + prefixLen = MIN(prefixLen, sizeof(prefixBuf)); + suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), "\x1B[0m"); + suffixLen = MIN(suffixLen, sizeof(suffixBuf)); + } switch (p_format->format) { case FORMAT_TAG: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%c/%-8s: ", priChar, entry->tag); - strcpy(suffixBuf, "\n"); suffixLen = 1; + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; break; case FORMAT_PROCESS: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c(%5d) ", priChar, entry->pid); - suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), + len = snprintf(suffixBuf + suffixLen, sizeof(suffixBuf) - suffixLen, " (%s)\n", entry->tag); + suffixLen += MIN(len, sizeof(suffixBuf) - suffixLen); + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, + "%c(%5d) ", priChar, entry->pid); break; case FORMAT_THREAD: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%c(%5d:%5d) ", priChar, entry->pid, entry->tid); - strcpy(suffixBuf, "\n"); - suffixLen = 1; + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; break; case FORMAT_RAW: - prefixBuf[0] = 0; - prefixLen = 0; - strcpy(suffixBuf, "\n"); - suffixLen = 1; + prefixBuf[prefixLen] = 0; + len = 0; + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; break; case FORMAT_TIME: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%s.%03ld %c/%-8s(%5d): ", timeBuf, entry->tv_nsec / 1000000, priChar, entry->tag, entry->pid); - strcpy(suffixBuf, "\n"); - suffixLen = 1; + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; break; case FORMAT_THREADTIME: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%s.%03ld %5d %5d %c %-8s: ", timeBuf, entry->tv_nsec / 1000000, entry->pid, entry->tid, priChar, entry->tag); - strcpy(suffixBuf, "\n"); - suffixLen = 1; + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; break; case FORMAT_LONG: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "[ %s.%03ld %5d:%5d %c/%-8s ]\n", timeBuf, entry->tv_nsec / 1000000, entry->pid, entry->tid, priChar, entry->tag); - strcpy(suffixBuf, "\n\n"); - suffixLen = 2; + strcpy(suffixBuf + suffixLen, "\n\n"); + suffixLen += 2; prefixSuffixIsHeaderFooter = 1; break; case FORMAT_BRIEF: default: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%c/%-8s(%5d): ", priChar, entry->tag, entry->pid); - strcpy(suffixBuf, "\n"); - suffixLen = 1; + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; break; } + /* snprintf has a weird return value. It returns what would have been * written given a large enough buffer. In the case that the prefix is * longer then our buffer(128), it messes up the calculations below * possibly causing heap corruption. To avoid this we double check and * set the length at the maximum (size minus null byte) */ - if(prefixLen >= sizeof(prefixBuf)) - prefixLen = sizeof(prefixBuf) - 1; - if(suffixLen >= sizeof(suffixBuf)) - suffixLen = sizeof(suffixBuf) - 1; + prefixLen += MIN(len, sizeof(prefixBuf) - prefixLen); + suffixLen = MIN(suffixLen, sizeof(suffixLen)); /* the following code is tragically unreadable */ size_t numLines; - size_t i; char *p; size_t bufferSize; const char *pm; @@ -938,88 +958,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 d1d9115..172b186 100644 --- a/liblog/tests/Android.mk +++ b/liblog/tests/Android.mk @@ -43,10 +43,6 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_CFLAGS += $(benchmark_c_flags) LOCAL_SHARED_LIBRARIES += liblog libm LOCAL_SRC_FILES := $(benchmark_src_files) -ifndef LOCAL_SDK_VERSION -LOCAL_C_INCLUDES += bionic bionic/libstdc++/include external/stlport/stlport -LOCAL_SHARED_LIBRARIES += libstlport -endif LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE) include $(BUILD_EXECUTABLE) @@ -59,7 +55,8 @@ test_c_flags := \ -g \ -Wall -Wextra \ -Werror \ - -fno-builtin + -fno-builtin \ + -std=gnu++11 test_src_files := \ liblog_test.cpp @@ -70,7 +67,7 @@ ifneq ($(wildcard $(LOCAL_PATH)/../../../../bionic/libc/bionic/libc_logging.cpp) test_src_files += \ libc_test.cpp -ifndef ($(TARGET_USES_LOGD),false) +ifneq ($(TARGET_USES_LOGD),false) test_c_flags += -DTARGET_USES_LOGD endif @@ -83,7 +80,6 @@ LOCAL_MODULE := $(test_module_prefix)unit-tests LOCAL_MODULE_TAGS := $(test_tags) LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_CFLAGS += $(test_c_flags) -LOCAL_LDLIBS := -lpthread LOCAL_SHARED_LIBRARIES := liblog LOCAL_SRC_FILES := $(test_src_files) include $(BUILD_NATIVE_TEST) diff --git a/liblog/tests/benchmark_main.cpp b/liblog/tests/benchmark_main.cpp index 090394c..e5ef970 100644 --- a/liblog/tests/benchmark_main.cpp +++ b/liblog/tests/benchmark_main.cpp @@ -17,6 +17,7 @@ #include <benchmark.h> #include <inttypes.h> +#include <math.h> #include <regex.h> #include <stdio.h> #include <stdlib.h> diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp index 0abc375..9839729 100644 --- a/liblog/tests/libc_test.cpp +++ b/liblog/tests/libc_test.cpp @@ -99,7 +99,7 @@ TEST(libc, __libc_fatal_no_abort) { 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))); + (log_id_t)LOG_ID_CRASH, O_RDONLY | O_NDELAY, 1000, pid))); char b[80]; struct timespec ts; @@ -119,7 +119,7 @@ TEST(libc, __libc_fatal_no_abort) { ASSERT_EQ(log_msg.entry.pid, pid); - if ((int)log_msg.id() != LOG_ID_MAIN) { + if ((int)log_msg.id() != LOG_ID_CRASH) { continue; } diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp index 39fe2ad..549d79e 100644 --- a/liblog/tests/liblog_benchmark.cpp +++ b/liblog/tests/liblog_benchmark.cpp @@ -99,7 +99,7 @@ static void BM_log_overhead(int iters) { } BENCHMARK(BM_log_overhead); -static void caught_latency(int signum) +static void caught_latency(int /*signum*/) { unsigned long long v = 0xDEADBEEFA55A5AA5ULL; @@ -193,7 +193,7 @@ static void BM_log_latency(int iters) { } BENCHMARK(BM_log_latency); -static void caught_delay(int signum) +static void caught_delay(int /*signum*/) { unsigned long long v = 0xDEADBEEFA55A5AA6ULL; diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp index 92b68ac..393e2cd 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 @@ -163,7 +164,7 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) { static unsigned signaled; log_time signal_time; -static void caught_blocking(int signum) +static void caught_blocking(int /*signum*/) { unsigned long long v = 0xDEADBEEFA55A0000ULL; @@ -543,7 +544,7 @@ TEST(liblog, too_big_payload) { 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)); + EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag))); } TEST(liblog, dual_reader) { @@ -612,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); +} |