diff options
Diffstat (limited to 'include/log')
-rw-r--r-- | include/log/log.h | 24 | ||||
-rw-r--r-- | include/log/log_read.h | 101 | ||||
-rw-r--r-- | include/log/logd.h | 1 | ||||
-rw-r--r-- | include/log/logger.h | 55 |
4 files changed, 144 insertions, 37 deletions
diff --git a/include/log/log.h b/include/log/log.h index 7f952ff..ace12d6 100644 --- a/include/log/log.h +++ b/include/log/log.h @@ -73,10 +73,11 @@ extern "C" { * Simplified macro to send a verbose log message using the current LOG_TAG. */ #ifndef ALOGV +#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) #if LOG_NDEBUG -#define ALOGV(...) ((void)0) +#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0) #else -#define ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#define ALOGV(...) __ALOGV(__VA_ARGS__) #endif #endif @@ -202,10 +203,11 @@ extern "C" { * Simplified macro to send a verbose system log message using the current LOG_TAG. */ #ifndef SLOGV +#define __SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) #if LOG_NDEBUG -#define SLOGV(...) ((void)0) +#define SLOGV(...) do { if (0) { __SLOGV(__VA_ARGS__); } } while (0) #else -#define SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#define SLOGV(...) __SLOGV(__VA_ARGS__) #endif #endif @@ -284,10 +286,11 @@ extern "C" { * Simplified macro to send a verbose radio log message using the current LOG_TAG. */ #ifndef RLOGV +#define __RLOGV(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) #if LOG_NDEBUG -#define RLOGV(...) ((void)0) +#define RLOGV(...) do { if (0) { __RLOGV(__VA_ARGS__); } } while (0) #else -#define RLOGV(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#define RLOGV(...) __RLOGV(__VA_ARGS__) #endif #endif @@ -488,7 +491,7 @@ typedef enum { #endif #ifndef LOG_EVENT_STRING #define LOG_EVENT_STRING(_tag, _value) \ - ((void) 0) /* not implemented -- must combine len with string */ + (void) __android_log_bswrite(_tag, _value); #endif /* TODO: something for LIST */ @@ -547,6 +550,7 @@ typedef enum log_id { LOG_ID_RADIO = 1, LOG_ID_EVENTS = 2, LOG_ID_SYSTEM = 3, + LOG_ID_CRASH = 4, LOG_ID_MAX } log_id_t; @@ -557,7 +561,11 @@ typedef enum log_id { * Send a simple string to the log. */ int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text); -int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...); +int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...) +#if defined(__GNUC__) + __attribute__((__format__(printf, 4, 5))) +#endif + ; #ifdef __cplusplus } diff --git a/include/log/log_read.h b/include/log/log_read.h index 861c192..946711a 100644 --- a/include/log/log_read.h +++ b/include/log/log_read.h @@ -17,23 +17,45 @@ #ifndef _LIBS_LOG_LOG_READ_H #define _LIBS_LOG_LOG_READ_H +#include <stdint.h> #include <time.h> +/* struct log_time is a wire-format variant of struct timespec */ #define NS_PER_SEC 1000000000ULL + #ifdef __cplusplus -struct log_time : public timespec { + +// NB: do NOT define a copy constructor. This will result in structure +// no longer being compatible with pass-by-value which is desired +// efficient behavior. Also, pass-by-reference breaks C/C++ ABI. +struct log_time { public: - log_time(timespec &T) + uint32_t tv_sec; // good to Feb 5 2106 + uint32_t tv_nsec; + + static const uint32_t tv_sec_max = 0xFFFFFFFFUL; + static const uint32_t tv_nsec_max = 999999999UL; + + log_time(const timespec &T) { tv_sec = T.tv_sec; tv_nsec = T.tv_nsec; } - log_time(void) + log_time(uint32_t sec, uint32_t nsec) + { + tv_sec = sec; + tv_nsec = nsec; + } + static const timespec EPOCH; + log_time() { } log_time(clockid_t id) { - clock_gettime(id, (timespec *) this); + timespec T; + clock_gettime(id, &T); + tv_sec = T.tv_sec; + tv_nsec = T.tv_nsec; } log_time(const char *T) { @@ -41,9 +63,12 @@ public: tv_sec = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); tv_nsec = c[4] | (c[5] << 8) | (c[6] << 16) | (c[7] << 24); } + + // timespec bool operator== (const timespec &T) const { - return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec); + return (tv_sec == static_cast<uint32_t>(T.tv_sec)) + && (tv_nsec == static_cast<uint32_t>(T.tv_nsec)); } bool operator!= (const timespec &T) const { @@ -51,8 +76,9 @@ public: } bool operator< (const timespec &T) const { - return (tv_sec < T.tv_sec) - || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec)); + return (tv_sec < static_cast<uint32_t>(T.tv_sec)) + || ((tv_sec == static_cast<uint32_t>(T.tv_sec)) + && (tv_nsec < static_cast<uint32_t>(T.tv_nsec))); } bool operator>= (const timespec &T) const { @@ -60,20 +86,73 @@ public: } bool operator> (const timespec &T) const { + return (tv_sec > static_cast<uint32_t>(T.tv_sec)) + || ((tv_sec == static_cast<uint32_t>(T.tv_sec)) + && (tv_nsec > static_cast<uint32_t>(T.tv_nsec))); + } + bool operator<= (const timespec &T) const + { + return !(*this > T); + } + log_time operator-= (const timespec &T); + log_time operator- (const timespec &T) const + { + log_time local(*this); + return local -= T; + } + + // log_time + bool operator== (const log_time &T) const + { + return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec); + } + bool operator!= (const log_time &T) const + { + return !(*this == T); + } + bool operator< (const log_time &T) const + { + return (tv_sec < T.tv_sec) + || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec)); + } + bool operator>= (const log_time &T) const + { + return !(*this < T); + } + bool operator> (const log_time &T) const + { return (tv_sec > T.tv_sec) || ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec)); } - bool operator<= (const timespec &T) const + bool operator<= (const log_time &T) const { return !(*this > T); } - uint64_t nsec(void) const + log_time operator-= (const log_time &T); + log_time operator- (const log_time &T) const + { + log_time local(*this); + return local -= T; + } + + uint64_t nsec() const { return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec; } -}; + + static const char default_format[]; + + // Add %#q for the fraction of a second to the standard library functions + char *strptime(const char *s, const char *format = default_format); +} __attribute__((__packed__)); + #else -typedef struct timespec log_time; + +typedef struct log_time { + uint32_t tv_sec; + uint32_t tv_nsec; +} __attribute__((__packed__)) log_time; + #endif #endif /* define _LIBS_LOG_LOG_READ_H */ diff --git a/include/log/logd.h b/include/log/logd.h index 379c373..2e6f220 100644 --- a/include/log/logd.h +++ b/include/log/logd.h @@ -41,6 +41,7 @@ extern "C" { int __android_log_bwrite(int32_t tag, const void *payload, size_t len); int __android_log_btwrite(int32_t tag, char type, const void *payload, size_t len); +int __android_log_bswrite(int32_t tag, const char *payload); #ifdef __cplusplus } diff --git a/include/log/logger.h b/include/log/logger.h index 966397a..53be1d3 100644 --- a/include/log/logger.h +++ b/include/log/logger.h @@ -12,6 +12,7 @@ #include <stdint.h> #include <log/log.h> +#include <log/log_read.h> #ifdef __cplusplus extern "C" { @@ -30,12 +31,12 @@ struct logger_entry { int32_t sec; /* seconds since Epoch */ int32_t nsec; /* nanoseconds */ char msg[0]; /* the entry's payload */ -}; +} __attribute__((__packed__)); /* * The userspace structure for version 2 of the logger_entry ABI. * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION) - * is called with version==2 + * is called with version==2; or used with the user space log daemon. */ struct logger_entry_v2 { uint16_t len; /* length of the payload */ @@ -46,13 +47,23 @@ struct logger_entry_v2 { int32_t nsec; /* nanoseconds */ uint32_t euid; /* effective UID of logger */ char msg[0]; /* the entry's payload */ -}; +} __attribute__((__packed__)); + +struct logger_entry_v3 { + uint16_t len; /* length of the payload */ + uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */ + int32_t pid; /* generating process's pid */ + int32_t tid; /* generating process's tid */ + int32_t sec; /* seconds since Epoch */ + int32_t nsec; /* nanoseconds */ + uint32_t lid; /* log id of the payload */ + char msg[0]; /* the entry's payload */ +} __attribute__((__packed__)); /* * The maximum size of the log entry payload that can be - * written to the kernel logger driver. An attempt to write - * more than this amount to /dev/log/* will result in a - * truncated log entry. + * written to the logger. An attempt to write more than + * this amount will result in a truncated log entry. */ #define LOGGER_ENTRY_MAX_PAYLOAD 4076 @@ -68,13 +79,10 @@ struct logger_entry_v2 { struct log_msg { union { unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; - struct logger_entry_v2 entry; + struct logger_entry_v3 entry; + struct logger_entry_v3 entry_v3; struct logger_entry_v2 entry_v2; struct logger_entry entry_v1; - struct { - unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; - log_id_t id; - } extra; } __attribute__((aligned(4))); #ifdef __cplusplus /* Matching log_time operators */ @@ -106,21 +114,21 @@ struct log_msg { { return !(*this > T); } - uint64_t nsec(void) const + uint64_t nsec() const { return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec; } /* packet methods */ - log_id_t id(void) + log_id_t id() { - return extra.id; + return (log_id_t) entry.lid; } - char *msg(void) + char *msg() { return entry.hdr_size ? (char *) buf + entry.hdr_size : entry_v1.msg; } - unsigned int len(void) + unsigned int len() { return (entry.hdr_size ? entry.hdr_size : sizeof(entry_v1)) + entry.len; } @@ -132,15 +140,26 @@ struct logger; log_id_t android_logger_get_id(struct logger *logger); int android_logger_clear(struct logger *logger); -int android_logger_get_log_size(struct logger *logger); -int android_logger_get_log_readable_size(struct logger *logger); +long android_logger_get_log_size(struct logger *logger); +int android_logger_set_log_size(struct logger *logger, unsigned long size); +long android_logger_get_log_readable_size(struct logger *logger); int android_logger_get_log_version(struct logger *logger); struct logger_list; +ssize_t android_logger_get_statistics(struct logger_list *logger_list, + char *buf, size_t len); +ssize_t android_logger_get_prune_list(struct logger_list *logger_list, + char *buf, size_t len); +int android_logger_set_prune_list(struct logger_list *logger_list, + char *buf, size_t len); + struct logger_list *android_logger_list_alloc(int mode, unsigned int tail, pid_t pid); +struct logger_list *android_logger_list_alloc_time(int mode, + log_time start, + pid_t pid); void android_logger_list_free(struct logger_list *logger_list); /* In the purest sense, the following two are orthogonal interfaces */ int android_logger_list_read(struct logger_list *logger_list, |