From 2ca4f49476a4e4e46dc7b47b2ce56ccaaadb9c8d Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 12 Sep 2016 11:54:57 -0700 Subject: [PATCH] liblog: add private android_log_write_list_buffer() Allows us to compose an event message for our own in-memory purposes. Will be used to compose an event message in logd and directly write it to just the pmsg buffer. Provide an internal enhanced C++ wrapper for event handling. Test: gTest liblog-unit-tests --gtest_filter=liblog.android_log_write_list_buffer Bug: 31456426 Change-Id: I98246898ba580f9e506baba8af2fd1b26a2a8aae --- include/log/log_event_list.h | 1 + include/private/android_logger.h | 41 ++++++++++++++++++++++++++++++++ liblog/log_event_list.c | 34 +++++++++++++++++++++++++- liblog/tests/liblog_test.cpp | 13 ++++++++++ 4 files changed, 88 insertions(+), 1 deletion(-) diff --git a/include/log/log_event_list.h b/include/log/log_event_list.h index 04c1cd6fb..31d49b2f9 100644 --- a/include/log/log_event_list.h +++ b/include/log/log_event_list.h @@ -116,6 +116,7 @@ int android_log_destroy(android_log_context* ctx); /* android_log_list C++ helpers */ extern "C++" { class android_log_event_list { +friend class __android_log_event_list; private: android_log_context ctx; diff --git a/include/private/android_logger.h b/include/private/android_logger.h index f3c6cf72d..9f81b1f06 100644 --- a/include/private/android_logger.h +++ b/include/private/android_logger.h @@ -25,6 +25,13 @@ #include #include +#if (defined(__cplusplus) && defined(_USING_LIBCXX)) +extern "C++" { +#include +} +#endif + +#include #include #define LOGGER_MAGIC 'l' @@ -146,6 +153,40 @@ bool __android_logger_property_get_bool(const char* key, int flag); unsigned long __android_logger_get_buffer_size(log_id_t logId); bool __android_logger_valid_buffer_size(unsigned long value); +/* Retrieve the composed event buffer */ +int android_log_write_list_buffer(android_log_context ctx, const char** msg); + +#ifdef __cplusplus +#ifdef __class_android_log_event_list_defined +#ifndef __class_android_log_event_list_private_defined +#define __class_android_log_event_list_private_defined +/* android_log_context C++ helpers */ +extern "C++" { +class __android_log_event_list : public android_log_event_list { + __android_log_event_list(const android_log_event_list&) = delete; + void operator =(const __android_log_event_list&) = delete; + +public: + explicit __android_log_event_list(int tag) : android_log_event_list(tag) { } + explicit __android_log_event_list(log_msg& log_msg) : android_log_event_list(log_msg) { } + +#if defined(_USING_LIBCXX) + operator std::string() { + if (ret) return std::string(""); + const char* cp = NULL; + ssize_t len = android_log_write_list_buffer(ctx, &cp); + if (len < 0) ret = len; + if (!cp || (len <= 0)) return std::string(""); + return std::string(cp, len); + } +#endif + +}; +} +#endif +#endif +#endif + #if defined(__cplusplus) } #endif diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c index 8303b6339..9ac1d30eb 100644 --- a/liblog/log_event_list.c +++ b/liblog/log_event_list.c @@ -320,7 +320,7 @@ LIBLOG_ABI_PUBLIC int android_log_write_list(android_log_context ctx, context->storage[1] = context->count[0]; len = context->len = context->pos; msg = (const char *)context->storage; - /* it'snot a list */ + /* it's not a list */ if (context->count[0] <= 1) { len -= sizeof(uint8_t) + sizeof(uint8_t); if (len < 0) { @@ -333,6 +333,38 @@ LIBLOG_ABI_PUBLIC int android_log_write_list(android_log_context ctx, __android_log_security_bwrite(context->tag, msg, len); } +LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx, + const char **buffer) { + android_log_context_internal *context; + const char *msg; + ssize_t len; + + context = (android_log_context_internal *)ctx; + if (!context || (kAndroidLoggerWrite != context->read_write_flag)) { + return -EBADF; + } + if (context->list_nest_depth) { + return -EIO; + } + if (buffer == NULL) { + return -EFAULT; + } + /* NB: if there was overflow, then log is truncated. Nothing reported */ + context->storage[1] = context->count[0]; + len = context->len = context->pos; + msg = (const char *)context->storage; + /* it's not a list */ + if (context->count[0] <= 1) { + len -= sizeof(uint8_t) + sizeof(uint8_t); + if (len < 0) { + len = 0; + } + msg += sizeof(uint8_t) + sizeof(uint8_t); + } + *buffer = msg; + return len; +} + /* * Extract a 4-byte value from a byte stream. */ diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp index 9c418c1d6..02a572d0a 100644 --- a/liblog/tests/liblog_test.cpp +++ b/liblog/tests/liblog_test.cpp @@ -2651,6 +2651,19 @@ TEST(liblog, create_android_logger_overflow) { ASSERT_TRUE(NULL == ctx); } +TEST(liblog, android_log_write_list_buffer) { + __android_log_event_list ctx(1005); + ctx << 1005 << "tag_def" << "(tag|1),(name|3),(format|3)"; + std::string buffer(ctx); + ctx.close(); + + char msgBuf[1024]; + memset(msgBuf, 0, sizeof(msgBuf)); + EXPECT_EQ(android_log_buffer_to_string(buffer.data(), buffer.length(), + msgBuf, sizeof(msgBuf)), 0); + EXPECT_STREQ(msgBuf, "[1005,tag_def,(tag|1),(name|3),(format|3)]"); +} + static const char __pmsg_file[] = "/data/william-shakespeare/MuchAdoAboutNothing.txt";