From b992d0d7d34bed62fd16151a68d60d58cc8003ef Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Thu, 20 Mar 2014 16:09:38 -0700 Subject: [PATCH] logd: liblog: Thread IDs missing from logcat -v thread - stuff caller's thread id into the packet. Bug: 13568206 Change-Id: I02d0cdf9b1d9e839ff8969f591db42dfe6e4cc95 --- liblog/logd_write.c | 37 ++++++++++++++++++++++++++++++------- logd/LogBuffer.cpp | 6 +++--- logd/LogBuffer.h | 3 ++- logd/LogBufferElement.cpp | 6 ++++-- logd/LogBufferElement.h | 5 ++++- logd/LogListener.cpp | 11 ++++++++--- 6 files changed, 51 insertions(+), 17 deletions(-) diff --git a/liblog/logd_write.c b/liblog/logd_write.c index c3efc33f7..aa0ad39c2 100644 --- a/liblog/logd_write.c +++ b/liblog/logd_write.c @@ -111,11 +111,34 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) */ return 0; } - struct iovec newVec[nr + 2]; + /* + * struct { + * // what we provide + * typeof_log_id_t log_id; + * u16 tid; + * log_time realtime; + * // caller provides + * union { + * struct { + * char prio; + * char payload[]; + * } string; + * struct { + * uint32_t tag + * char payload[]; + * } binary; + * }; + * }; + */ + 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(); 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); @@ -123,17 +146,17 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) realtime_ts.tv_sec = ts.tv_sec; realtime_ts.tv_nsec = ts.tv_nsec; - newVec[1].iov_base = (unsigned char *) &realtime_ts; - newVec[1].iov_len = sizeof(log_time); + newVec[2].iov_base = (unsigned char *) &realtime_ts; + newVec[2].iov_len = sizeof(log_time); size_t i; - for (i = 2; i < nr + 2; i++) { - newVec[i].iov_base = vec[i-2].iov_base; - newVec[i].iov_len = vec[i-2].iov_len; + 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; } /* The write below could be lost, but will never block. */ - return writev(logd_fd, newVec, nr + 2); + return writev(logd_fd, newVec, nr + header_length); #endif } diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index 197b7e8b3..1c5cef03b 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -45,13 +45,13 @@ LogBuffer::LogBuffer(LastLogTimes *times) } void LogBuffer::log(log_id_t log_id, log_time realtime, - uid_t uid, pid_t pid, const char *msg, - unsigned short len) { + uid_t uid, pid_t pid, pid_t tid, + const char *msg, unsigned short len) { if ((log_id >= LOG_ID_MAX) || (log_id < 0)) { return; } LogBufferElement *elem = new LogBufferElement(log_id, realtime, - uid, pid, msg, len); + uid, pid, tid, msg, len); pthread_mutex_lock(&mLogElementsLock); diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h index 0745e5604..cbbb2ce3e 100644 --- a/logd/LogBuffer.h +++ b/logd/LogBuffer.h @@ -48,7 +48,8 @@ public: LogBuffer(LastLogTimes *times); void log(log_id_t log_id, log_time realtime, - uid_t uid, pid_t pid, const char *msg, unsigned short len); + uid_t uid, pid_t pid, pid_t tid, + const char *msg, unsigned short len); log_time flushTo(SocketClient *writer, const log_time start, bool privileged, bool (*filter)(const LogBufferElement *element, void *arg) = NULL, diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp index 8d45f3466..d959ceb46 100644 --- a/logd/LogBufferElement.cpp +++ b/logd/LogBufferElement.cpp @@ -27,11 +27,12 @@ const log_time LogBufferElement::FLUSH_ERROR((uint32_t)0, (uint32_t)0); LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, - uid_t uid, pid_t pid, const char *msg, - unsigned short len) + uid_t uid, pid_t pid, pid_t tid, + const char *msg, unsigned short len) : mLogId(log_id) , mUid(uid) , mPid(pid) + , mTid(tid) , mMsgLen(len) , mMonotonicTime(CLOCK_MONOTONIC) , mRealTime(realtime) { @@ -50,6 +51,7 @@ log_time LogBufferElement::flushTo(SocketClient *reader) { entry.len = mMsgLen; entry.lid = mLogId; entry.pid = mPid; + entry.tid = mTid; entry.sec = mRealTime.tv_sec; entry.nsec = mRealTime.tv_nsec; diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h index 1da09aea6..fdca973fe 100644 --- a/logd/LogBufferElement.h +++ b/logd/LogBufferElement.h @@ -26,6 +26,7 @@ class LogBufferElement { const log_id_t mLogId; const uid_t mUid; const pid_t mPid; + const pid_t mTid; char *mMsg; const unsigned short mMsgLen; const log_time mMonotonicTime; @@ -33,12 +34,14 @@ class LogBufferElement { public: LogBufferElement(log_id_t log_id, log_time realtime, - uid_t uid, pid_t pid, const char *msg, unsigned short len); + uid_t uid, pid_t pid, pid_t tid, + const char *msg, unsigned short len); virtual ~LogBufferElement(); log_id_t getLogId() const { return mLogId; } uid_t getUid(void) const { return mUid; } pid_t getPid(void) const { return mPid; } + pid_t getTid(void) const { return mTid; } unsigned short getMsgLen() const { return mMsgLen; } log_time getMonotonicTime(void) const { return mMonotonicTime; } log_time getRealTime(void) const { return mRealTime; } diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp index 2aa2ebb00..bef2097da 100644 --- a/logd/LogListener.cpp +++ b/logd/LogListener.cpp @@ -50,7 +50,7 @@ bool LogListener::onDataAvailable(SocketClient *cli) { int socket = cli->getSocket(); ssize_t n = recvmsg(socket, &hdr, 0); - if (n <= (ssize_t) sizeof_log_id_t) { + if (n <= (sizeof_log_id_t + sizeof(uint16_t) + sizeof(log_time))) { return false; } @@ -82,17 +82,22 @@ bool LogListener::onDataAvailable(SocketClient *cli) { if (log_id < 0 || log_id >= LOG_ID_MAX) { return false; } - char *msg = ((char *)buffer) + sizeof_log_id_t; n -= sizeof_log_id_t; + // second element is the thread id of the caller + pid_t tid = (pid_t) *((uint16_t *) msg); + msg += sizeof(uint16_t); + n -= sizeof(uint16_t); + + // third element is the realtime at point of caller log_time realtime(msg); msg += sizeof(log_time); n -= sizeof(log_time); unsigned short len = n; if (len == n) { - logbuf->log(log_id, realtime, cred->uid, cred->pid, msg, len); + logbuf->log(log_id, realtime, cred->uid, cred->pid, tid, msg, len); reader->notifyNewLog(); }