From 9787f9a0546b8974bdbb9661158d8facb69aa325 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Tue, 19 May 2020 19:01:16 -0700 Subject: [PATCH] logd: format LogBufferElement and LogStatistics correctly Test: logging unit tests Change-Id: If63be065e38f2a1c4cf2807ceaa9eea180b16c51 --- logd/ChattyLogBuffer.cpp | 133 +++++------ logd/LogBufferElement.cpp | 156 ++++++------ logd/LogBufferElement.h | 84 +++---- logd/LogStatistics.cpp | 177 +++++++------- logd/LogStatistics.h | 485 ++++++++++++++++---------------------- logd/LogWhiteBlackList.h | 4 +- logd/SimpleLogBuffer.cpp | 34 +-- 7 files changed, 479 insertions(+), 594 deletions(-) diff --git a/logd/ChattyLogBuffer.cpp b/logd/ChattyLogBuffer.cpp index 0ba602596..c2e89fcf2 100644 --- a/logd/ChattyLogBuffer.cpp +++ b/logd/ChattyLogBuffer.cpp @@ -48,38 +48,33 @@ ChattyLogBuffer::~ChattyLogBuffer() {} enum match_type { DIFFERENT, SAME, SAME_LIBLOG }; -static enum match_type Identical(LogBufferElement* elem, LogBufferElement* last) { - // is it mostly identical? - // if (!elem) return DIFFERENT; - ssize_t lenl = elem->getMsgLen(); +static enum match_type Identical(const LogBufferElement& elem, const LogBufferElement& last) { + ssize_t lenl = elem.msg_len(); if (lenl <= 0) return DIFFERENT; // value if this represents a chatty elem - // if (!last) return DIFFERENT; - ssize_t lenr = last->getMsgLen(); + ssize_t lenr = last.msg_len(); if (lenr <= 0) return DIFFERENT; // value if this represents a chatty elem - // if (elem->getLogId() != last->getLogId()) return DIFFERENT; - if (elem->getUid() != last->getUid()) return DIFFERENT; - if (elem->getPid() != last->getPid()) return DIFFERENT; - if (elem->getTid() != last->getTid()) return DIFFERENT; + if (elem.uid() != last.uid()) return DIFFERENT; + if (elem.pid() != last.pid()) return DIFFERENT; + if (elem.tid() != last.tid()) return DIFFERENT; // last is more than a minute old, stop squashing identical messages - if (elem->getRealTime().nsec() > (last->getRealTime().nsec() + 60 * NS_PER_SEC)) - return DIFFERENT; + if (elem.realtime().nsec() > (last.realtime().nsec() + 60 * NS_PER_SEC)) return DIFFERENT; // Identical message - const char* msgl = elem->getMsg(); - const char* msgr = last->getMsg(); + const char* msgl = elem.msg(); + const char* msgr = last.msg(); if (lenl == lenr) { if (!fastcmp(msgl, msgr, lenl)) return SAME; // liblog tagged messages (content gets summed) - if (elem->getLogId() == LOG_ID_EVENTS && lenl == sizeof(android_log_event_int_t) && + if (elem.log_id() == LOG_ID_EVENTS && lenl == sizeof(android_log_event_int_t) && !fastcmp(msgl, msgr, sizeof(android_log_event_int_t) - sizeof(int32_t)) && - elem->getTag() == LIBLOG_LOG_TAG) { + elem.GetTag() == LIBLOG_LOG_TAG) { return SAME_LIBLOG; } } // audit message (except sequence number) identical? - if (last->isBinary() && lenl > static_cast(sizeof(android_log_event_string_t)) && + if (last.IsBinary() && lenl > static_cast(sizeof(android_log_event_string_t)) && lenr > static_cast(sizeof(android_log_event_string_t))) { if (fastcmp(msgl, msgr, sizeof(android_log_event_string_t) - sizeof(int32_t))) { return DIFFERENT; @@ -105,11 +100,11 @@ static enum match_type Identical(LogBufferElement* elem, LogBufferElement* last) void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) { // b/137093665: don't coalesce security messages. - if (elem.getLogId() == LOG_ID_SECURITY) { + if (elem.log_id() == LOG_ID_SECURITY) { SimpleLogBuffer::LogInternal(std::move(elem)); return; } - int log_id = elem.getLogId(); + int log_id = elem.log_id(); // Initialize last_logged_elements_ to a copy of elem if logging the first element for a log_id. if (!last_logged_elements_[log_id]) { @@ -119,12 +114,12 @@ void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) { } LogBufferElement& current_last = *last_logged_elements_[log_id]; - enum match_type match = Identical(&elem, ¤t_last); + enum match_type match = Identical(elem, current_last); if (match == DIFFERENT) { if (duplicate_elements_[log_id]) { // If we previously had 3+ identical messages, log the chatty message. - if (duplicate_elements_[log_id]->getDropped() > 0) { + if (duplicate_elements_[log_id]->dropped_count() > 0) { SimpleLogBuffer::LogInternal(std::move(*duplicate_elements_[log_id])); } duplicate_elements_[log_id].reset(); @@ -146,10 +141,10 @@ void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) { // 3+ identical LIBLOG event messages: coalesce them into last_logged_elements_. if (match == SAME_LIBLOG) { const android_log_event_int_t* current_last_event = - reinterpret_cast(current_last.getMsg()); + reinterpret_cast(current_last.msg()); int64_t current_last_count = current_last_event->payload.data; android_log_event_int_t* elem_event = - reinterpret_cast(const_cast(elem.getMsg())); + reinterpret_cast(const_cast(elem.msg())); int64_t elem_count = elem_event->payload.data; int64_t total = current_last_count + elem_count; @@ -158,22 +153,22 @@ void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) { last_logged_elements_[log_id].emplace(std::move(elem)); return; } - stats()->AddTotal(current_last.getLogId(), current_last.getMsgLen()); + stats()->AddTotal(current_last.log_id(), current_last.msg_len()); elem_event->payload.data = total; last_logged_elements_[log_id].emplace(std::move(elem)); return; } // 3+ identical messages (not LIBLOG) messages: increase the drop count. - uint16_t dropped_count = duplicate_elements_[log_id]->getDropped(); + uint16_t dropped_count = duplicate_elements_[log_id]->dropped_count(); if (dropped_count == std::numeric_limits::max()) { SimpleLogBuffer::LogInternal(std::move(*duplicate_elements_[log_id])); dropped_count = 0; } // We're dropping the current_last log so add its stats to the total. - stats()->AddTotal(current_last.getLogId(), current_last.getMsgLen()); + stats()->AddTotal(current_last.log_id(), current_last.msg_len()); // Use current_last for tracking the dropped count to always use the latest timestamp. - current_last.setDropped(dropped_count + 1); + current_last.SetDropped(dropped_count + 1); duplicate_elements_[log_id].emplace(std::move(current_last)); last_logged_elements_[log_id].emplace(std::move(elem)); } @@ -181,14 +176,13 @@ void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) { LogBufferElementCollection::iterator ChattyLogBuffer::Erase(LogBufferElementCollection::iterator it, bool coalesce) { LogBufferElement& element = *it; - log_id_t id = element.getLogId(); + log_id_t id = element.log_id(); // Remove iterator references in the various lists that will become stale // after the element is erased from the main logging list. { // start of scope for found iterator - int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element.getTag() - : element.getUid(); + int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element.GetTag() : element.uid(); LogBufferIteratorMap::iterator found = mLastWorst[id].find(key); if ((found != mLastWorst[id].end()) && (it == found->second)) { mLastWorst[id].erase(found); @@ -196,10 +190,10 @@ LogBufferElementCollection::iterator ChattyLogBuffer::Erase(LogBufferElementColl } { // start of scope for pid found iterator - // element->getUid() may not be AID_SYSTEM for next-best-watermark. + // element->uid() may not be AID_SYSTEM for next-best-watermark. // will not assume id != LOG_ID_EVENTS or LOG_ID_SECURITY for KISS and // long term code stability, find() check should be fast for those ids. - LogBufferPidIteratorMap::iterator found = mLastWorstPidOfSystem[id].find(element.getPid()); + LogBufferPidIteratorMap::iterator found = mLastWorstPidOfSystem[id].find(element.pid()); if (found != mLastWorstPidOfSystem[id].end() && it == found->second) { mLastWorstPidOfSystem[id].erase(found); } @@ -207,14 +201,13 @@ LogBufferElementCollection::iterator ChattyLogBuffer::Erase(LogBufferElementColl #ifdef DEBUG_CHECK_FOR_STALE_ENTRIES LogBufferElementCollection::iterator bad = it; - int key = - (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element->getTag() : element->getUid(); + int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element->GetTag() : element->uid(); #endif if (coalesce) { - stats()->Erase(&element); + stats()->Erase(element); } else { - stats()->Subtract(&element); + stats()->Subtract(element); } it = SimpleLogBuffer::Erase(it); @@ -245,15 +238,15 @@ class LogBufferElementLast { public: bool coalesce(LogBufferElement* element, uint16_t dropped) { - uint64_t key = LogBufferElementKey(element->getUid(), element->getPid(), element->getTid()); + uint64_t key = LogBufferElementKey(element->uid(), element->pid(), element->tid()); LogBufferElementMap::iterator it = map.find(key); if (it != map.end()) { LogBufferElement* found = it->second; - uint16_t moreDropped = found->getDropped(); + uint16_t moreDropped = found->dropped_count(); if ((dropped + moreDropped) > USHRT_MAX) { map.erase(it); } else { - found->setDropped(dropped + moreDropped); + found->SetDropped(dropped + moreDropped); return true; } } @@ -261,18 +254,18 @@ class LogBufferElementLast { } void add(LogBufferElement* element) { - uint64_t key = LogBufferElementKey(element->getUid(), element->getPid(), element->getTid()); + uint64_t key = LogBufferElementKey(element->uid(), element->pid(), element->tid()); map[key] = element; } void clear() { map.clear(); } void clear(LogBufferElement* element) { - uint64_t current = element->getRealTime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC); + uint64_t current = element->realtime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC); for (LogBufferElementMap::iterator it = map.begin(); it != map.end();) { LogBufferElement* mapElement = it->second; - if (mapElement->getDropped() >= EXPIRE_THRESHOLD && - current > mapElement->getRealTime().nsec()) { + if (mapElement->dropped_count() >= EXPIRE_THRESHOLD && + current > mapElement->realtime().nsec()) { it = map.erase(it); } else { ++it; @@ -359,12 +352,12 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u while (it != logs().end()) { LogBufferElement& element = *it; - if (element.getLogId() != id || element.getUid() != caller_uid) { + if (element.log_id() != id || element.uid() != caller_uid) { ++it; continue; } - if (oldest && oldest->start() <= element.getSequence()) { + if (oldest && oldest->start() <= element.sequence()) { busy = true; KickReader(oldest, id, pruneRows); break; @@ -382,7 +375,7 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u bool hasBlacklist = (id != LOG_ID_SECURITY) && prune_->naughty(); while (!clearAll && (pruneRows > 0)) { // recalculate the worst offender on every batched pass - int worst = -1; // not valid for getUid() or getKey() + int worst = -1; // not valid for uid() or getKey() size_t worst_sizes = 0; size_t second_worst_sizes = 0; pid_t worstPid = 0; // POSIX guarantees PID != 0 @@ -445,19 +438,19 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u while (it != logs().end()) { LogBufferElement& element = *it; - if (oldest && oldest->start() <= element.getSequence()) { + if (oldest && oldest->start() <= element.sequence()) { busy = true; // Do not let chatty eliding trigger any reader mitigation break; } - if (element.getLogId() != id) { + if (element.log_id() != id) { ++it; continue; } - // below this point element->getLogId() == id + // below this point element->log_id() == id - uint16_t dropped = element.getDropped(); + uint16_t dropped = element.dropped_count(); // remove any leading drops if (leading && dropped) { @@ -470,8 +463,8 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u continue; } - int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element.getTag() - : element.getUid(); + int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element.GetTag() + : element.uid(); if (hasBlacklist && prune_->naughty(&element)) { last.clear(&element); @@ -490,25 +483,25 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u if (worst_sizes < second_worst_sizes) { break; } - worst_sizes -= element.getMsgLen(); + worst_sizes -= element.msg_len(); } continue; } - if (element.getRealTime() < (lastt->getRealTime() - too_old) || - element.getRealTime() > lastt->getRealTime()) { + if (element.realtime() < (lastt->realtime() - too_old) || + element.realtime() > lastt->realtime()) { break; } if (dropped) { last.add(&element); - if (worstPid && ((!gc && element.getPid() == worstPid) || - mLastWorstPidOfSystem[id].find(element.getPid()) == + if (worstPid && ((!gc && element.pid() == worstPid) || + mLastWorstPidOfSystem[id].find(element.pid()) == mLastWorstPidOfSystem[id].end())) { - // element->getUid() may not be AID_SYSTEM, next best + // element->uid() may not be AID_SYSTEM, next best // watermark if current one empty. id is not LOG_ID_EVENTS // or LOG_ID_SECURITY because of worstPid check. - mLastWorstPidOfSystem[id][element.getPid()] = it; + mLastWorstPidOfSystem[id][element.pid()] = it; } if ((!gc && !worstPid && (key == worst)) || (mLastWorst[id].find(key) == mLastWorst[id].end())) { @@ -518,14 +511,14 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u continue; } - if (key != worst || (worstPid && element.getPid() != worstPid)) { + if (key != worst || (worstPid && element.pid() != worstPid)) { leading = false; last.clear(&element); ++it; continue; } // key == worst below here - // If worstPid set, then element->getPid() == worstPid below here + // If worstPid set, then element->pid() == worstPid below here pruneRows--; if (pruneRows == 0) { @@ -534,21 +527,21 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u kick = true; - uint16_t len = element.getMsgLen(); + uint16_t len = element.msg_len(); // do not create any leading drops if (leading) { it = Erase(it); } else { - stats()->Drop(&element); - element.setDropped(1); + stats()->Drop(element); + element.SetDropped(1); if (last.coalesce(&element, 1)) { it = Erase(it, true); } else { last.add(&element); if (worstPid && (!gc || mLastWorstPidOfSystem[id].find(worstPid) == mLastWorstPidOfSystem[id].end())) { - // element->getUid() may not be AID_SYSTEM, next best + // element->uid() may not be AID_SYSTEM, next best // watermark if current one empty. id is not // LOG_ID_EVENTS or LOG_ID_SECURITY because of worstPid. mLastWorstPidOfSystem[id][worstPid] = it; @@ -577,18 +570,18 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u while ((pruneRows > 0) && (it != logs().end())) { LogBufferElement& element = *it; - if (element.getLogId() != id) { + if (element.log_id() != id) { it++; continue; } - if (oldest && oldest->start() <= element.getSequence()) { + if (oldest && oldest->start() <= element.sequence()) { busy = true; if (!whitelist) KickReader(oldest, id, pruneRows); break; } - if (hasWhitelist && !element.getDropped() && prune_->nice(&element)) { + if (hasWhitelist && !element.dropped_count() && prune_->nice(&element)) { // WhiteListed whitelist = true; it++; @@ -605,12 +598,12 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u while ((it != logs().end()) && (pruneRows > 0)) { LogBufferElement& element = *it; - if (element.getLogId() != id) { + if (element.log_id() != id) { ++it; continue; } - if (oldest && oldest->start() <= element.getSequence()) { + if (oldest && oldest->start() <= element.sequence()) { busy = true; KickReader(oldest, id, pruneRows); break; diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp index c6dbda86d..172a75786 100644 --- a/logd/LogBufferElement.cpp +++ b/logd/LogBufferElement.cpp @@ -32,92 +32,92 @@ LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, uint64_t sequence, const char* msg, uint16_t len) - : mUid(uid), - mPid(pid), - mTid(tid), - mSequence(sequence), - mRealTime(realtime), - mMsgLen(len), - mLogId(log_id), - mDropped(false) { - mMsg = new char[len]; - memcpy(mMsg, msg, len); + : uid_(uid), + pid_(pid), + tid_(tid), + sequence_(sequence), + realtime_(realtime), + msg_len_(len), + log_id_(log_id), + dropped_(false) { + msg_ = new char[len]; + memcpy(msg_, msg, len); } LogBufferElement::LogBufferElement(const LogBufferElement& elem) - : mUid(elem.mUid), - mPid(elem.mPid), - mTid(elem.mTid), - mSequence(elem.mSequence), - mRealTime(elem.mRealTime), - mMsgLen(elem.mMsgLen), - mLogId(elem.mLogId), - mDropped(elem.mDropped) { - if (mDropped) { - mTag = elem.getTag(); + : uid_(elem.uid_), + pid_(elem.pid_), + tid_(elem.tid_), + sequence_(elem.sequence_), + realtime_(elem.realtime_), + msg_len_(elem.msg_len_), + log_id_(elem.log_id_), + dropped_(elem.dropped_) { + if (dropped_) { + tag_ = elem.GetTag(); } else { - mMsg = new char[mMsgLen]; - memcpy(mMsg, elem.mMsg, mMsgLen); + msg_ = new char[msg_len_]; + memcpy(msg_, elem.msg_, msg_len_); } } LogBufferElement::LogBufferElement(LogBufferElement&& elem) - : mUid(elem.mUid), - mPid(elem.mPid), - mTid(elem.mTid), - mSequence(elem.mSequence), - mRealTime(elem.mRealTime), - mMsgLen(elem.mMsgLen), - mLogId(elem.mLogId), - mDropped(elem.mDropped) { - if (mDropped) { - mTag = elem.getTag(); + : uid_(elem.uid_), + pid_(elem.pid_), + tid_(elem.tid_), + sequence_(elem.sequence_), + realtime_(elem.realtime_), + msg_len_(elem.msg_len_), + log_id_(elem.log_id_), + dropped_(elem.dropped_) { + if (dropped_) { + tag_ = elem.GetTag(); } else { - mMsg = elem.mMsg; - elem.mMsg = nullptr; + msg_ = elem.msg_; + elem.msg_ = nullptr; } } LogBufferElement::~LogBufferElement() { - if (!mDropped) { - delete[] mMsg; + if (!dropped_) { + delete[] msg_; } } -uint32_t LogBufferElement::getTag() const { +uint32_t LogBufferElement::GetTag() const { // Binary buffers have no tag. - if (!isBinary()) { + if (!IsBinary()) { return 0; } - // Dropped messages store the tag in place of mMsg. - if (mDropped) { - return mTag; + // Dropped messages store the tag in place of msg_. + if (dropped_) { + return tag_; } // For non-dropped messages, we get the tag from the message header itself. - if (mMsgLen < sizeof(android_event_header_t)) { + if (msg_len_ < sizeof(android_event_header_t)) { return 0; } - return reinterpret_cast(mMsg)->tag; + return reinterpret_cast(msg_)->tag; } -uint16_t LogBufferElement::setDropped(uint16_t value) { - if (mDropped) { - return mDroppedCount = value; +uint16_t LogBufferElement::SetDropped(uint16_t value) { + if (dropped_) { + return dropped_count_ = value; } - // The tag information is saved in mMsg data, which is in a union with mTag, used after mDropped - // is set to true. Therefore we save the tag value aside, delete mMsg, then set mTag to the tag + // The tag information is saved in msg_ data, which is in a union with tag_, used after dropped_ + // is set to true. Therefore we save the tag value aside, delete msg_, then set tag_ to the tag // value in its place. - auto old_tag = getTag(); - delete[] mMsg; - mMsg = nullptr; + auto old_tag = GetTag(); + delete[] msg_; + msg_ = nullptr; - mTag = old_tag; - mDropped = true; - return mDroppedCount = value; + tag_ = old_tag; + dropped_ = true; + return dropped_count_ = value; } // caller must own and free character string @@ -165,8 +165,8 @@ char* android::tidToName(pid_t tid) { return retval; } -// assumption: mMsg == NULL -size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogStatistics* stats, +// assumption: msg_ == NULL +size_t LogBufferElement::PopulateDroppedMessage(char*& buffer, LogStatistics* stats, bool lastSame) { static const char tag[] = "chatty"; @@ -176,13 +176,13 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogStatistics* st } static const char format_uid[] = "uid=%u%s%s %s %u line%s"; - const char* name = stats->UidToName(mUid); - const char* commName = android::tidToName(mTid); - if (!commName && (mTid != mPid)) { - commName = android::tidToName(mPid); + const char* name = stats->UidToName(uid_); + const char* commName = android::tidToName(tid_); + if (!commName && (tid_ != pid_)) { + commName = android::tidToName(pid_); } if (!commName) { - commName = stats->PidToName(mPid); + commName = stats->PidToName(pid_); } if (name && name[0] && commName && (name[0] == commName[0])) { size_t len = strlen(name + 1); @@ -214,12 +214,11 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogStatistics* st } // identical to below to calculate the buffer size required const char* type = lastSame ? "identical" : "expire"; - size_t len = snprintf(nullptr, 0, format_uid, mUid, name ? name : "", - commName ? commName : "", type, getDropped(), - (getDropped() > 1) ? "s" : ""); + size_t len = snprintf(nullptr, 0, format_uid, uid_, name ? name : "", commName ? commName : "", + type, dropped_count(), (dropped_count() > 1) ? "s" : ""); size_t hdrLen; - if (isBinary()) { + if (IsBinary()) { hdrLen = sizeof(android_log_event_string_t); } else { hdrLen = 1 + sizeof(tag); @@ -233,7 +232,7 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogStatistics* st } size_t retval = hdrLen + len; - if (isBinary()) { + if (IsBinary()) { android_log_event_string_t* event = reinterpret_cast(buffer); @@ -246,9 +245,8 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogStatistics* st strcpy(buffer + 1, tag); } - snprintf(buffer + hdrLen, len + 1, format_uid, mUid, name ? name : "", - commName ? commName : "", type, getDropped(), - (getDropped() > 1) ? "s" : ""); + snprintf(buffer + hdrLen, len + 1, format_uid, uid_, name ? name : "", commName ? commName : "", + type, dropped_count(), (dropped_count() > 1) ? "s" : ""); free(const_cast(name)); free(const_cast(commName)); @@ -259,22 +257,22 @@ bool LogBufferElement::FlushTo(LogWriter* writer, LogStatistics* stats, bool las struct logger_entry entry = {}; entry.hdr_size = sizeof(struct logger_entry); - entry.lid = mLogId; - entry.pid = mPid; - entry.tid = mTid; - entry.uid = mUid; - entry.sec = mRealTime.tv_sec; - entry.nsec = mRealTime.tv_nsec; + entry.lid = log_id_; + entry.pid = pid_; + entry.tid = tid_; + entry.uid = uid_; + entry.sec = realtime_.tv_sec; + entry.nsec = realtime_.tv_nsec; char* buffer = nullptr; const char* msg; - if (mDropped) { - entry.len = populateDroppedMessage(buffer, stats, lastSame); + if (dropped_) { + entry.len = PopulateDroppedMessage(buffer, stats, lastSame); if (!entry.len) return true; msg = buffer; } else { - msg = mMsg; - entry.len = mMsgLen; + msg = msg_; + entry.len = msg_len_; } bool retval = writer->Write(entry, msg); diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h index 35252f9c9..5b13e32c7 100644 --- a/logd/LogBufferElement.h +++ b/logd/LogBufferElement.h @@ -33,26 +33,6 @@ class LogStatistics; #define EXPIRE_RATELIMIT 10 // maximum rate in seconds to report expiration class __attribute__((packed)) LogBufferElement { - // sized to match reality of incoming log packets - const uint32_t mUid; - const uint32_t mPid; - const uint32_t mTid; - uint64_t mSequence; - log_time mRealTime; - union { - char* mMsg; // mDropped == false - int32_t mTag; // mDropped == true - }; - union { - const uint16_t mMsgLen; // mDropped == false - uint16_t mDroppedCount; // mDropped == true - }; - const uint8_t mLogId; - bool mDropped; - - // assumption: mDropped == true - size_t populateDroppedMessage(char*& buffer, LogStatistics* parent, bool lastSame); - public: LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, uint64_t sequence, const char* msg, uint16_t len); @@ -60,37 +40,41 @@ class __attribute__((packed)) LogBufferElement { LogBufferElement(LogBufferElement&& elem); ~LogBufferElement(); - bool isBinary(void) const { - return (mLogId == LOG_ID_EVENTS) || (mLogId == LOG_ID_SECURITY); - } + bool IsBinary() const { return (log_id_ == LOG_ID_EVENTS) || (log_id_ == LOG_ID_SECURITY); } - log_id_t getLogId() const { - return static_cast(mLogId); - } - uid_t getUid(void) const { - return mUid; - } - pid_t getPid(void) const { - return mPid; - } - pid_t getTid(void) const { - return mTid; - } - uint32_t getTag() const; - uint16_t getDropped(void) const { - return mDropped ? mDroppedCount : 0; - } - uint16_t setDropped(uint16_t value); - uint16_t getMsgLen() const { - return mDropped ? 0 : mMsgLen; - } - const char* getMsg() const { - return mDropped ? nullptr : mMsg; - } - uint64_t getSequence() const { return mSequence; } - log_time getRealTime(void) const { - return mRealTime; - } + uint32_t GetTag() const; + uint16_t SetDropped(uint16_t value); bool FlushTo(LogWriter* writer, LogStatistics* parent, bool lastSame); + + log_id_t log_id() const { return static_cast(log_id_); } + uid_t uid() const { return uid_; } + pid_t pid() const { return pid_; } + pid_t tid() const { return tid_; } + uint16_t msg_len() const { return dropped_ ? 0 : msg_len_; } + const char* msg() const { return dropped_ ? nullptr : msg_; } + uint64_t sequence() const { return sequence_; } + log_time realtime() const { return realtime_; } + uint16_t dropped_count() const { return dropped_ ? dropped_count_ : 0; } + + private: + // assumption: mDropped == true + size_t PopulateDroppedMessage(char*& buffer, LogStatistics* parent, bool lastSame); + + // sized to match reality of incoming log packets + const uint32_t uid_; + const uint32_t pid_; + const uint32_t tid_; + uint64_t sequence_; + log_time realtime_; + union { + char* msg_; // mDropped == false + int32_t tag_; // mDropped == true + }; + union { + const uint16_t msg_len_; // mDropped == false + uint16_t dropped_count_; // mDropped == true + }; + const uint8_t log_id_; + bool dropped_; }; diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp index bb7621d2f..a2acab7aa 100644 --- a/logd/LogStatistics.cpp +++ b/logd/LogStatistics.cpp @@ -87,10 +87,10 @@ void LogStatistics::AddTotal(log_id_t log_id, uint16_t size) { ++mElementsTotal[log_id]; } -void LogStatistics::Add(LogBufferElement* element) { +void LogStatistics::Add(const LogBufferElement& element) { auto lock = std::lock_guard{lock_}; - log_id_t log_id = element->getLogId(); - uint16_t size = element->getMsgLen(); + log_id_t log_id = element.log_id(); + uint16_t size = element.msg_len(); mSizes[log_id] += size; ++mElements[log_id]; @@ -99,7 +99,7 @@ void LogStatistics::Add(LogBufferElement* element) { // evaluated and trimmed, thus recording size and number of // elements, but we must recognize the manufactured dropped // entry as not contributing to the lifetime totals. - if (element->getDropped()) { + if (element.dropped_count()) { ++mDroppedElements[log_id]; } else { mSizesTotal[log_id] += size; @@ -107,7 +107,7 @@ void LogStatistics::Add(LogBufferElement* element) { ++mElementsTotal[log_id]; } - log_time stamp(element->getRealTime()); + log_time stamp(element.realtime()); if (mNewest[log_id] < stamp) { // A major time update invalidates the statistics :-( log_time diff = stamp - mNewest[log_id]; @@ -132,111 +132,111 @@ void LogStatistics::Add(LogBufferElement* element) { return; } - uidTable[log_id].add(element->getUid(), element); - if (element->getUid() == AID_SYSTEM) { - pidSystemTable[log_id].add(element->getPid(), element); + uidTable[log_id].Add(element.uid(), element); + if (element.uid() == AID_SYSTEM) { + pidSystemTable[log_id].Add(element.pid(), element); } if (!enable) { return; } - pidTable.add(element->getPid(), element); - tidTable.add(element->getTid(), element); + pidTable.Add(element.pid(), element); + tidTable.Add(element.tid(), element); - uint32_t tag = element->getTag(); + uint32_t tag = element.GetTag(); if (tag) { if (log_id == LOG_ID_SECURITY) { - securityTagTable.add(tag, element); + securityTagTable.Add(tag, element); } else { - tagTable.add(tag, element); + tagTable.Add(tag, element); } } - if (!element->getDropped()) { - tagNameTable.add(TagNameKey(element), element); + if (!element.dropped_count()) { + tagNameTable.Add(TagNameKey(element), element); } } -void LogStatistics::Subtract(LogBufferElement* element) { +void LogStatistics::Subtract(const LogBufferElement& element) { auto lock = std::lock_guard{lock_}; - log_id_t log_id = element->getLogId(); - uint16_t size = element->getMsgLen(); + log_id_t log_id = element.log_id(); + uint16_t size = element.msg_len(); mSizes[log_id] -= size; --mElements[log_id]; - if (element->getDropped()) { + if (element.dropped_count()) { --mDroppedElements[log_id]; } - if (mOldest[log_id] < element->getRealTime()) { - mOldest[log_id] = element->getRealTime(); + if (mOldest[log_id] < element.realtime()) { + mOldest[log_id] = element.realtime(); } if (log_id == LOG_ID_KERNEL) { return; } - uidTable[log_id].subtract(element->getUid(), element); - if (element->getUid() == AID_SYSTEM) { - pidSystemTable[log_id].subtract(element->getPid(), element); + uidTable[log_id].Subtract(element.uid(), element); + if (element.uid() == AID_SYSTEM) { + pidSystemTable[log_id].Subtract(element.pid(), element); } if (!enable) { return; } - pidTable.subtract(element->getPid(), element); - tidTable.subtract(element->getTid(), element); + pidTable.Subtract(element.pid(), element); + tidTable.Subtract(element.tid(), element); - uint32_t tag = element->getTag(); + uint32_t tag = element.GetTag(); if (tag) { if (log_id == LOG_ID_SECURITY) { - securityTagTable.subtract(tag, element); + securityTagTable.Subtract(tag, element); } else { - tagTable.subtract(tag, element); + tagTable.Subtract(tag, element); } } - if (!element->getDropped()) { - tagNameTable.subtract(TagNameKey(element), element); + if (!element.dropped_count()) { + tagNameTable.Subtract(TagNameKey(element), element); } } // Atomically set an entry to drop // entry->setDropped(1) must follow this call, caller should do this explicitly. -void LogStatistics::Drop(LogBufferElement* element) { +void LogStatistics::Drop(const LogBufferElement& element) { auto lock = std::lock_guard{lock_}; - log_id_t log_id = element->getLogId(); - uint16_t size = element->getMsgLen(); + log_id_t log_id = element.log_id(); + uint16_t size = element.msg_len(); mSizes[log_id] -= size; ++mDroppedElements[log_id]; - if (mNewestDropped[log_id] < element->getRealTime()) { - mNewestDropped[log_id] = element->getRealTime(); + if (mNewestDropped[log_id] < element.realtime()) { + mNewestDropped[log_id] = element.realtime(); } - uidTable[log_id].drop(element->getUid(), element); - if (element->getUid() == AID_SYSTEM) { - pidSystemTable[log_id].drop(element->getPid(), element); + uidTable[log_id].Drop(element.uid(), element); + if (element.uid() == AID_SYSTEM) { + pidSystemTable[log_id].Drop(element.pid(), element); } if (!enable) { return; } - pidTable.drop(element->getPid(), element); - tidTable.drop(element->getTid(), element); + pidTable.Drop(element.pid(), element); + tidTable.Drop(element.tid(), element); - uint32_t tag = element->getTag(); + uint32_t tag = element.GetTag(); if (tag) { if (log_id == LOG_ID_SECURITY) { - securityTagTable.drop(tag, element); + securityTagTable.Drop(tag, element); } else { - tagTable.drop(tag, element); + tagTable.Drop(tag, element); } } - tagNameTable.subtract(TagNameKey(element), element); + tagNameTable.Subtract(TagNameKey(element), element); } const char* LogStatistics::UidToName(uid_t uid) const { @@ -283,8 +283,8 @@ const char* LogStatistics::UidToNameLocked(uid_t uid) const { ++it) { const PidEntry& entry = it->second; - if (entry.getUid() == uid) { - const char* nameTmp = entry.getName(); + if (entry.uid() == uid) { + const char* nameTmp = entry.name(); if (nameTmp) { if (!name) { @@ -314,8 +314,8 @@ void LogStatistics::WorstTwoWithThreshold(const LogHashtable& tabl *worst_sizes = max_entries[0]->getSizes(); // b/24782000: Allow time horizon to extend roughly tenfold, assume average entry length is // 100 characters. - if (*worst_sizes > threshold && *worst_sizes > (10 * max_entries[0]->getDropped())) { - *worst = max_entries[0]->getKey(); + if (*worst_sizes > threshold && *worst_sizes > (10 * max_entries[0]->dropped_count())) { + *worst = max_entries[0]->key(); *second_worst_sizes = max_entries[1]->getSizes(); if (*second_worst_sizes < threshold) { *second_worst_sizes = threshold; @@ -344,7 +344,7 @@ void LogStatistics::WorstTwoSystemPids(log_id id, size_t worst_uid_sizes, int* w return; } - *worst = max_entries[0]->getKey(); + *worst = max_entries[0]->key(); *second_worst_sizes = worst_uid_sizes - max_entries[0]->getSizes() + max_entries[1]->getSizes(); } @@ -393,9 +393,8 @@ void LogStatistics::FormatTmp(const char* nameTmp, uid_t uid, std::string& name, if (!nameTmp) nameTmp = allocNameTmp = UidToNameLocked(uid); if (nameTmp) { size_t lenSpace = std::max(nameLen - name.length(), (size_t)1); - size_t len = EntryBaseConstants::total_len - - EntryBaseConstants::pruned_len - size.length() - - name.length() - lenSpace - 2; + size_t len = EntryBase::TOTAL_LEN - EntryBase::PRUNED_LEN - size.length() - name.length() - + lenSpace - 2; size_t lenNameTmp = strlen(nameTmp); while ((len < lenNameTmp) && (lenSpace > 1)) { ++len; @@ -412,11 +411,10 @@ void LogStatistics::FormatTmp(const char* nameTmp, uid_t uid, std::string& name, } std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUIRES(stat.lock_) { - uid_t uid = getUid(); - std::string name = android::base::StringPrintf("%u", uid); + std::string name = android::base::StringPrintf("%u", uid_); std::string size = android::base::StringPrintf("%zu", getSizes()); - stat.FormatTmp(nullptr, uid, name, size, 6); + stat.FormatTmp(nullptr, uid_, name, size, 6); std::string pruned = ""; if (worstUidEnabledForLogid(id)) { @@ -424,7 +422,7 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI for (LogStatistics::uidTable_t::const_iterator it = stat.uidTable[id].begin(); it != stat.uidTable[id].end(); ++it) { - totalDropped += it->second.getDropped(); + totalDropped += it->second.dropped_count(); } size_t sizes = stat.mSizes[id]; size_t totalSize = stat.mSizesTotal[id]; @@ -434,7 +432,7 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI size_t entrySize = getSizes(); float virtualEntrySize = entrySize; int realPermille = virtualEntrySize * 1000.0 / sizes; - size_t dropped = getDropped(); + size_t dropped = dropped_count(); if (dropped) { pruned = android::base::StringPrintf("%zu", dropped); virtualEntrySize += (float)dropped * totalSize / totalElements; @@ -461,8 +459,7 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI change = android::base::StringPrintf( "%s%d%s", prefix, (permille + 5) / 10, units); } - ssize_t spaces = EntryBaseConstants::pruned_len - 2 - - pruned.length() - change.length(); + ssize_t spaces = EntryBase::PRUNED_LEN - 2 - pruned.length() - change.length(); if ((spaces <= 0) && pruned.length()) { spaces = 1; } @@ -475,13 +472,13 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI std::string output = formatLine(name, size, pruned); - if (uid != AID_SYSTEM) { + if (uid_ != AID_SYSTEM) { return output; } static const size_t maximum_sorted_entries = 32; std::array sorted; - stat.pidSystemTable[id].MaxEntries(uid, 0, &sorted); + stat.pidSystemTable[id].MaxEntries(uid_, 0, &sorted); std::string byPid; size_t index; @@ -494,7 +491,7 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI if (entry->getSizes() <= (getSizes() / 100)) { break; } - if (entry->getDropped()) { + if (entry->dropped_count()) { hasDropped = true; } byPid += entry->format(stat, id); @@ -518,15 +515,13 @@ std::string PidEntry::formatHeader(const std::string& name, std::string PidEntry::format(const LogStatistics& stat, log_id_t /* id */) const REQUIRES(stat.lock_) { - uid_t uid = getUid(); - pid_t pid = getPid(); - std::string name = android::base::StringPrintf("%5u/%u", pid, uid); + std::string name = android::base::StringPrintf("%5u/%u", pid_, uid_); std::string size = android::base::StringPrintf("%zu", getSizes()); - stat.FormatTmp(getName(), uid, name, size, 12); + stat.FormatTmp(name_, uid_, name, size, 12); std::string pruned = ""; - size_t dropped = getDropped(); + size_t dropped = dropped_count(); if (dropped) { pruned = android::base::StringPrintf("%zu", dropped); } @@ -543,14 +538,13 @@ std::string TidEntry::formatHeader(const std::string& name, std::string TidEntry::format(const LogStatistics& stat, log_id_t /* id */) const REQUIRES(stat.lock_) { - uid_t uid = getUid(); - std::string name = android::base::StringPrintf("%5u/%u", getTid(), uid); + std::string name = android::base::StringPrintf("%5u/%u", tid(), uid_); std::string size = android::base::StringPrintf("%zu", getSizes()); - stat.FormatTmp(getName(), uid, name, size, 12); + stat.FormatTmp(name_, uid_, name, size, 12); std::string pruned = ""; - size_t dropped = getDropped(); + size_t dropped = dropped_count(); if (dropped) { pruned = android::base::StringPrintf("%zu", dropped); } @@ -569,13 +563,12 @@ std::string TagEntry::formatHeader(const std::string& name, log_id_t id) const { std::string TagEntry::format(const LogStatistics& /* stat */, log_id_t /* id */) const { std::string name; - uid_t uid = getUid(); - if (uid == (uid_t)-1) { - name = android::base::StringPrintf("%7u", getKey()); + if (uid_ == (uid_t)-1) { + name = android::base::StringPrintf("%7u", key()); } else { - name = android::base::StringPrintf("%7u/%u", getKey(), uid); + name = android::base::StringPrintf("%7u/%u", key(), uid_); } - const char* nameTmp = getName(); + const char* nameTmp = this->name(); if (nameTmp) { name += android::base::StringPrintf( "%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", nameTmp); @@ -584,7 +577,7 @@ std::string TagEntry::format(const LogStatistics& /* stat */, std::string size = android::base::StringPrintf("%zu", getSizes()); std::string pruned = ""; - size_t dropped = getDropped(); + size_t dropped = dropped_count(); if (dropped) { pruned = android::base::StringPrintf("%zu", dropped); } @@ -602,34 +595,30 @@ std::string TagNameEntry::formatHeader(const std::string& name, std::string TagNameEntry::format(const LogStatistics& /* stat */, log_id_t /* id */) const { std::string name; - pid_t tid = getTid(); - pid_t pid = getPid(); std::string pidstr; - if (pid != (pid_t)-1) { - pidstr = android::base::StringPrintf("%u", pid); - if ((tid != (pid_t)-1) && (tid != pid)) pidstr = "/" + pidstr; + if (pid_ != (pid_t)-1) { + pidstr = android::base::StringPrintf("%u", pid_); + if (tid_ != (pid_t)-1 && tid_ != pid_) pidstr = "/" + pidstr; } int len = 9 - pidstr.length(); if (len < 0) len = 0; - if ((tid == (pid_t)-1) || (tid == pid)) { + if (tid_ == (pid_t)-1 || tid_ == pid_) { name = android::base::StringPrintf("%*s", len, ""); } else { - name = android::base::StringPrintf("%*u", len, tid); + name = android::base::StringPrintf("%*u", len, tid_); } name += pidstr; - uid_t uid = getUid(); - if (uid != (uid_t)-1) { - name += android::base::StringPrintf("/%u", uid); + if (uid_ != (uid_t)-1) { + name += android::base::StringPrintf("/%u", uid_); } std::string size = android::base::StringPrintf("%zu", getSizes()); - const char* nameTmp = getName(); + const char* nameTmp = this->name(); if (nameTmp) { size_t lenSpace = std::max(16 - name.length(), (size_t)1); - size_t len = EntryBaseConstants::total_len - - EntryBaseConstants::pruned_len - size.length() - - name.length() - lenSpace - 2; + size_t len = EntryBase::TOTAL_LEN - EntryBase::PRUNED_LEN - size.length() - name.length() - + lenSpace - 2; size_t lenNameTmp = strlen(nameTmp); while ((len < lenNameTmp) && (lenSpace > 1)) { ++len; @@ -944,7 +933,7 @@ uid_t pidToUid(pid_t pid) { uid_t LogStatistics::PidToUid(pid_t pid) { auto lock = std::lock_guard{lock_}; - return pidTable.add(pid)->second.getUid(); + return pidTable.Add(pid)->second.uid(); } // caller must free character string @@ -952,7 +941,7 @@ const char* LogStatistics::PidToName(pid_t pid) const { auto lock = std::lock_guard{lock_}; // An inconvenient truth ... getName() can alter the object pidTable_t& writablePidTable = const_cast(pidTable); - const char* name = writablePidTable.add(pid)->second.getName(); + const char* name = writablePidTable.Add(pid)->second.name(); if (!name) { return nullptr; } diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h index 7d13ff757..6a46adbd9 100644 --- a/logd/LogStatistics.h +++ b/logd/LogStatistics.h @@ -65,7 +65,7 @@ class LogHashtable { static const size_t unordered_map_per_entry_overhead = sizeof(void*); static const size_t unordered_map_bucket_overhead = sizeof(void*); - public: + public: size_t size() const { return map.size(); } @@ -90,10 +90,10 @@ class LogHashtable { for (const_iterator it = map.begin(); it != map.end(); ++it) { const TEntry& entry = it->second; - if ((uid != AID_ROOT) && (uid != entry.getUid())) { + if (uid != AID_ROOT && uid != entry.uid()) { continue; } - if (pid && entry.getPid() && (pid != entry.getPid())) { + if (pid && entry.pid() && pid != entry.pid()) { continue; } @@ -113,95 +113,67 @@ class LogHashtable { } } - inline iterator add(const TKey& key, const LogBufferElement* element) { + iterator Add(const TKey& key, const LogBufferElement& element) { iterator it = map.find(key); if (it == map.end()) { it = map.insert(std::make_pair(key, TEntry(element))).first; } else { - it->second.add(element); + it->second.Add(element); } return it; } - inline iterator add(TKey key) { + iterator Add(const TKey& key) { iterator it = map.find(key); if (it == map.end()) { it = map.insert(std::make_pair(key, TEntry(key))).first; } else { - it->second.add(key); + it->second.Add(key); } return it; } - void subtract(TKey&& key, const LogBufferElement* element) { - iterator it = map.find(std::move(key)); - if ((it != map.end()) && it->second.subtract(element)) { - map.erase(it); - } - } - - void subtract(const TKey& key, const LogBufferElement* element) { + void Subtract(const TKey& key, const LogBufferElement& element) { iterator it = map.find(key); - if ((it != map.end()) && it->second.subtract(element)) { + if (it != map.end() && it->second.Subtract(element)) { map.erase(it); } } - inline void drop(TKey key, const LogBufferElement* element) { + void Drop(const TKey& key, const LogBufferElement& element) { iterator it = map.find(key); if (it != map.end()) { - it->second.drop(element); + it->second.Drop(element); } } - inline iterator begin() { - return map.begin(); - } - inline const_iterator begin() const { - return map.begin(); - } - inline iterator end() { - return map.end(); - } - inline const_iterator end() const { - return map.end(); - } + iterator begin() { return map.begin(); } + const_iterator begin() const { return map.begin(); } + iterator end() { return map.end(); } + const_iterator end() const { return map.end(); } }; -namespace EntryBaseConstants { -static constexpr size_t pruned_len = 14; -static constexpr size_t total_len = 80; -} +class EntryBase { + public: + EntryBase() : size_(0) {} + explicit EntryBase(const LogBufferElement& element) : size_(element.msg_len()) {} -struct EntryBase { - size_t size; + size_t getSizes() const { return size_; } - EntryBase() : size(0) { - } - explicit EntryBase(const LogBufferElement* element) - : size(element->getMsgLen()) { + void Add(const LogBufferElement& element) { size_ += element.msg_len(); } + bool Subtract(const LogBufferElement& element) { + size_ -= element.msg_len(); + return !size_; } - size_t getSizes() const { - return size; - } - - inline void add(const LogBufferElement* element) { - size += element->getMsgLen(); - } - inline bool subtract(const LogBufferElement* element) { - size -= element->getMsgLen(); - return !size; - } + static constexpr size_t PRUNED_LEN = 14; + static constexpr size_t TOTAL_LEN = 80; static std::string formatLine(const std::string& name, const std::string& size, const std::string& pruned) { - ssize_t drop_len = - std::max(pruned.length() + 1, EntryBaseConstants::pruned_len); - ssize_t size_len = - std::max(size.length() + 1, EntryBaseConstants::total_len - - name.length() - drop_len - 1); + ssize_t drop_len = std::max(pruned.length() + 1, PRUNED_LEN); + ssize_t size_len = std::max(size.length() + 1, TOTAL_LEN - name.length() - drop_len - 1); std::string ret = android::base::StringPrintf( "%s%*s%*s", name.c_str(), (int)size_len, size.c_str(), @@ -213,258 +185,220 @@ struct EntryBase { if (len) ret.erase(pos + 1, len); return ret + "\n"; } + + private: + size_t size_; }; -struct EntryBaseDropped : public EntryBase { - size_t dropped; +class EntryBaseDropped : public EntryBase { + public: + EntryBaseDropped() : dropped_(0) {} + explicit EntryBaseDropped(const LogBufferElement& element) + : EntryBase(element), dropped_(element.dropped_count()) {} - EntryBaseDropped() : dropped(0) { + size_t dropped_count() const { return dropped_; } + + void Add(const LogBufferElement& element) { + dropped_ += element.dropped_count(); + EntryBase::Add(element); } - explicit EntryBaseDropped(const LogBufferElement* element) - : EntryBase(element), dropped(element->getDropped()) { + bool Subtract(const LogBufferElement& element) { + dropped_ -= element.dropped_count(); + return EntryBase::Subtract(element) && !dropped_; + } + void Drop(const LogBufferElement& element) { + dropped_ += 1; + EntryBase::Subtract(element); } - size_t getDropped() const { - return dropped; - } - - inline void add(const LogBufferElement* element) { - dropped += element->getDropped(); - EntryBase::add(element); - } - inline bool subtract(const LogBufferElement* element) { - dropped -= element->getDropped(); - return EntryBase::subtract(element) && !dropped; - } - inline void drop(const LogBufferElement* element) { - dropped += 1; - EntryBase::subtract(element); - } + private: + size_t dropped_; }; -struct UidEntry : public EntryBaseDropped { - const uid_t uid; - pid_t pid; +class UidEntry : public EntryBaseDropped { + public: + explicit UidEntry(const LogBufferElement& element) + : EntryBaseDropped(element), uid_(element.uid()), pid_(element.pid()) {} - explicit UidEntry(const LogBufferElement* element) - : EntryBaseDropped(element), - uid(element->getUid()), - pid(element->getPid()) { - } + uid_t key() const { return uid_; } + uid_t uid() const { return key(); } + pid_t pid() const { return pid_; } - inline const uid_t& getKey() const { - return uid; - } - inline const uid_t& getUid() const { - return getKey(); - } - inline const pid_t& getPid() const { - return pid; - } - - inline void add(const LogBufferElement* element) { - if (pid != element->getPid()) { - pid = -1; + void Add(const LogBufferElement& element) { + if (pid_ != element.pid()) { + pid_ = -1; } - EntryBaseDropped::add(element); + EntryBaseDropped::Add(element); } std::string formatHeader(const std::string& name, log_id_t id) const; std::string format(const LogStatistics& stat, log_id_t id) const; + + private: + const uid_t uid_; + pid_t pid_; }; namespace android { uid_t pidToUid(pid_t pid); } -struct PidEntry : public EntryBaseDropped { - const pid_t pid; - uid_t uid; - char* name; - +class PidEntry : public EntryBaseDropped { + public: explicit PidEntry(pid_t pid) : EntryBaseDropped(), - pid(pid), - uid(android::pidToUid(pid)), - name(android::pidToName(pid)) { - } - explicit PidEntry(const LogBufferElement* element) + pid_(pid), + uid_(android::pidToUid(pid)), + name_(android::pidToName(pid)) {} + explicit PidEntry(const LogBufferElement& element) : EntryBaseDropped(element), - pid(element->getPid()), - uid(element->getUid()), - name(android::pidToName(pid)) { - } + pid_(element.pid()), + uid_(element.uid()), + name_(android::pidToName(pid_)) {} PidEntry(const PidEntry& element) : EntryBaseDropped(element), - pid(element.pid), - uid(element.uid), - name(element.name ? strdup(element.name) : nullptr) { - } - ~PidEntry() { - free(name); - } + pid_(element.pid_), + uid_(element.uid_), + name_(element.name_ ? strdup(element.name_) : nullptr) {} + ~PidEntry() { free(name_); } - const pid_t& getKey() const { - return pid; - } - const pid_t& getPid() const { - return getKey(); - } - const uid_t& getUid() const { - return uid; - } - const char* getName() const { - return name; - } + pid_t key() const { return pid_; } + pid_t pid() const { return key(); } + uid_t uid() const { return uid_; } + const char* name() const { return name_; } - inline void add(pid_t newPid) { - if (name && !fastcmp(name, "zygote", 6)) { - free(name); - name = nullptr; + void Add(pid_t new_pid) { + if (name_ && !fastcmp(name_, "zygote", 6)) { + free(name_); + name_ = nullptr; } - if (!name) { - name = android::pidToName(newPid); + if (!name_) { + name_ = android::pidToName(new_pid); } } - inline void add(const LogBufferElement* element) { - uid_t incomingUid = element->getUid(); - if (getUid() != incomingUid) { - uid = incomingUid; - free(name); - name = android::pidToName(element->getPid()); + void Add(const LogBufferElement& element) { + uid_t incoming_uid = element.uid(); + if (uid() != incoming_uid) { + uid_ = incoming_uid; + free(name_); + name_ = android::pidToName(element.pid()); } else { - add(element->getPid()); + Add(element.pid()); } - EntryBaseDropped::add(element); + EntryBaseDropped::Add(element); } std::string formatHeader(const std::string& name, log_id_t id) const; std::string format(const LogStatistics& stat, log_id_t id) const; + + private: + const pid_t pid_; + uid_t uid_; + char* name_; }; -struct TidEntry : public EntryBaseDropped { - const pid_t tid; - pid_t pid; - uid_t uid; - char* name; - +class TidEntry : public EntryBaseDropped { + public: TidEntry(pid_t tid, pid_t pid) : EntryBaseDropped(), - tid(tid), - pid(pid), - uid(android::pidToUid(tid)), - name(android::tidToName(tid)) { - } - explicit TidEntry(const LogBufferElement* element) + tid_(tid), + pid_(pid), + uid_(android::pidToUid(tid)), + name_(android::tidToName(tid)) {} + explicit TidEntry(const LogBufferElement& element) : EntryBaseDropped(element), - tid(element->getTid()), - pid(element->getPid()), - uid(element->getUid()), - name(android::tidToName(tid)) { - } + tid_(element.tid()), + pid_(element.pid()), + uid_(element.uid()), + name_(android::tidToName(tid_)) {} TidEntry(const TidEntry& element) : EntryBaseDropped(element), - tid(element.tid), - pid(element.pid), - uid(element.uid), - name(element.name ? strdup(element.name) : nullptr) { - } - ~TidEntry() { - free(name); - } + tid_(element.tid_), + pid_(element.pid_), + uid_(element.uid_), + name_(element.name_ ? strdup(element.name_) : nullptr) {} + ~TidEntry() { free(name_); } - const pid_t& getKey() const { - return tid; - } - const pid_t& getTid() const { - return getKey(); - } - const pid_t& getPid() const { - return pid; - } - const uid_t& getUid() const { - return uid; - } - const char* getName() const { - return name; - } + pid_t key() const { return tid_; } + pid_t tid() const { return key(); } + pid_t pid() const { return pid_; } + uid_t uid() const { return uid_; } + const char* name() const { return name_; } - inline void add(pid_t incomingTid) { - if (name && !fastcmp(name, "zygote", 6)) { - free(name); - name = nullptr; + void Add(pid_t incomingTid) { + if (name_ && !fastcmp(name_, "zygote", 6)) { + free(name_); + name_ = nullptr; } - if (!name) { - name = android::tidToName(incomingTid); + if (!name_) { + name_ = android::tidToName(incomingTid); } } - inline void add(const LogBufferElement* element) { - uid_t incomingUid = element->getUid(); - pid_t incomingPid = element->getPid(); - if ((getUid() != incomingUid) || (getPid() != incomingPid)) { - uid = incomingUid; - pid = incomingPid; - free(name); - name = android::tidToName(element->getTid()); + void Add(const LogBufferElement& element) { + uid_t incoming_uid = element.uid(); + pid_t incoming_pid = element.pid(); + if (uid() != incoming_uid || pid() != incoming_pid) { + uid_ = incoming_uid; + pid_ = incoming_pid; + free(name_); + name_ = android::tidToName(element.tid()); } else { - add(element->getTid()); + Add(element.tid()); } - EntryBaseDropped::add(element); + EntryBaseDropped::Add(element); } std::string formatHeader(const std::string& name, log_id_t id) const; std::string format(const LogStatistics& stat, log_id_t id) const; + + private: + const pid_t tid_; + pid_t pid_; + uid_t uid_; + char* name_; }; -struct TagEntry : public EntryBaseDropped { - const uint32_t tag; - pid_t pid; - uid_t uid; - - explicit TagEntry(const LogBufferElement* element) +class TagEntry : public EntryBaseDropped { + public: + explicit TagEntry(const LogBufferElement& element) : EntryBaseDropped(element), - tag(element->getTag()), - pid(element->getPid()), - uid(element->getUid()) { - } + tag_(element.GetTag()), + pid_(element.pid()), + uid_(element.uid()) {} - const uint32_t& getKey() const { - return tag; - } - const pid_t& getPid() const { - return pid; - } - const uid_t& getUid() const { - return uid; - } - const char* getName() const { - return android::tagToName(tag); - } + uint32_t key() const { return tag_; } + pid_t pid() const { return pid_; } + uid_t uid() const { return uid_; } + const char* name() const { return android::tagToName(tag_); } - inline void add(const LogBufferElement* element) { - if (uid != element->getUid()) { - uid = -1; + void Add(const LogBufferElement& element) { + if (uid_ != element.uid()) { + uid_ = -1; } - if (pid != element->getPid()) { - pid = -1; + if (pid_ != element.pid()) { + pid_ = -1; } - EntryBaseDropped::add(element); + EntryBaseDropped::Add(element); } std::string formatHeader(const std::string& name, log_id_t id) const; std::string format(const LogStatistics& stat, log_id_t id) const; + + private: + const uint32_t tag_; + pid_t pid_; + uid_t uid_; }; struct TagNameKey { std::string* alloc; std::string_view name; // Saves space if const char* - explicit TagNameKey(const LogBufferElement* element) - : alloc(nullptr), name("", strlen("")) { - if (element->isBinary()) { - uint32_t tag = element->getTag(); + explicit TagNameKey(const LogBufferElement& element) : alloc(nullptr), name("", strlen("")) { + if (element.IsBinary()) { + uint32_t tag = element.GetTag(); if (tag) { const char* cp = android::tagToName(tag); if (cp) { @@ -478,13 +412,13 @@ struct TagNameKey { name = std::string_view(alloc->c_str(), alloc->size()); return; } - const char* msg = element->getMsg(); + const char* msg = element.msg(); if (!msg) { name = std::string_view("chatty", strlen("chatty")); return; } ++msg; - uint16_t len = element->getMsgLen(); + uint16_t len = element.msg_len(); len = (len <= 1) ? 0 : strnlen(msg, len - 1); if (!len) { name = std::string_view("", strlen("")); @@ -544,54 +478,43 @@ struct std::hash } }; -struct TagNameEntry : public EntryBase { - pid_t tid; - pid_t pid; - uid_t uid; - TagNameKey name; - - explicit TagNameEntry(const LogBufferElement* element) +class TagNameEntry : public EntryBase { + public: + explicit TagNameEntry(const LogBufferElement& element) : EntryBase(element), - tid(element->getTid()), - pid(element->getPid()), - uid(element->getUid()), - name(element) { - } + tid_(element.tid()), + pid_(element.pid()), + uid_(element.uid()), + name_(element) {} - const TagNameKey& getKey() const { - return name; - } - const pid_t& getTid() const { - return tid; - } - const pid_t& getPid() const { - return pid; - } - const uid_t& getUid() const { - return uid; - } - const char* getName() const { - return name.data(); - } - size_t getNameAllocLength() const { - return name.getAllocLength(); - } + const TagNameKey& key() const { return name_; } + pid_t tid() const { return tid_; } + pid_t pid() const { return pid_; } + uid_t uid() const { return uid_; } + const char* name() const { return name_.data(); } + size_t getNameAllocLength() const { return name_.getAllocLength(); } - inline void add(const LogBufferElement* element) { - if (uid != element->getUid()) { - uid = -1; + void Add(const LogBufferElement& element) { + if (uid_ != element.uid()) { + uid_ = -1; } - if (pid != element->getPid()) { - pid = -1; + if (pid_ != element.pid()) { + pid_ = -1; } - if (tid != element->getTid()) { - tid = -1; + if (tid_ != element.tid()) { + tid_ = -1; } - EntryBase::add(element); + EntryBase::Add(element); } std::string formatHeader(const std::string& name, log_id_t id) const; std::string format(const LogStatistics& stat, log_id_t id) const; + + private: + pid_t tid_; + pid_t pid_; + uid_t uid_; + TagNameKey name_; }; // Log Statistics @@ -645,11 +568,11 @@ class LogStatistics { (pidTable.size() * sizeof(pidTable_t::iterator)) + (tagTable.size() * sizeof(tagTable_t::iterator)); for (auto it : pidTable) { - const char* name = it.second.getName(); + const char* name = it.second.name(); if (name) size += strlen(name) + 1; } for (auto it : tidTable) { - const char* name = it.second.getName(); + const char* name = it.second.name(); if (name) size += strlen(name) + 1; } for (auto it : tagNameTable) size += it.second.getNameAllocLength(); @@ -667,14 +590,14 @@ class LogStatistics { LogStatistics(bool enable_statistics); void AddTotal(log_id_t log_id, uint16_t size) EXCLUDES(lock_); - void Add(LogBufferElement* entry) EXCLUDES(lock_); - void Subtract(LogBufferElement* entry) EXCLUDES(lock_); + void Add(const LogBufferElement& entry) EXCLUDES(lock_); + void Subtract(const LogBufferElement& entry) EXCLUDES(lock_); // entry->setDropped(1) must follow this call - void Drop(LogBufferElement* entry) EXCLUDES(lock_); + void Drop(const LogBufferElement& entry) EXCLUDES(lock_); // Correct for coalescing two entries referencing dropped content - void Erase(LogBufferElement* element) EXCLUDES(lock_) { + void Erase(const LogBufferElement& element) EXCLUDES(lock_) { auto lock = std::lock_guard{lock_}; - log_id_t log_id = element->getLogId(); + log_id_t log_id = element.log_id(); --mElements[log_id]; --mDroppedElements[log_id]; } diff --git a/logd/LogWhiteBlackList.h b/logd/LogWhiteBlackList.h index 0e4e8371f..447ab87be 100644 --- a/logd/LogWhiteBlackList.h +++ b/logd/LogWhiteBlackList.h @@ -43,9 +43,7 @@ class Prune { return mPid; } - int cmp(LogBufferElement* e) const { - return cmp(e->getUid(), e->getPid()); - } + int cmp(LogBufferElement* e) const { return cmp(e->uid(), e->pid()); } std::string format(); }; diff --git a/logd/SimpleLogBuffer.cpp b/logd/SimpleLogBuffer.cpp index aaa74ae19..79ce06971 100644 --- a/logd/SimpleLogBuffer.cpp +++ b/logd/SimpleLogBuffer.cpp @@ -44,7 +44,7 @@ std::list::iterator SimpleLogBuffer::GetOldest(log_id_t log_id if (oldest_[log_id]) { it = *oldest_[log_id]; } - while (it != logs().end() && it->getLogId() != log_id) { + while (it != logs().end() && it->log_id() != log_id) { it++; } if (it != logs().end()) { @@ -102,10 +102,10 @@ int SimpleLogBuffer::Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pi } void SimpleLogBuffer::LogInternal(LogBufferElement&& elem) { - log_id_t log_id = elem.getLogId(); + log_id_t log_id = elem.log_id(); logs_.emplace_back(std::move(elem)); - stats_->Add(&logs_.back()); + stats_->Add(logs_.back()); MaybePrune(log_id); reader_list_->NotifyNewLog(1 << log_id); } @@ -146,9 +146,9 @@ bool SimpleLogBuffer::FlushTo( for (it = logs_.end(); it != logs_.begin(); /* do nothing */) { --it; - if (it->getSequence() == state.start()) { + if (it->sequence() == state.start()) { break; - } else if (it->getSequence() < state.start()) { + } else if (it->sequence() < state.start()) { it++; break; } @@ -158,19 +158,19 @@ bool SimpleLogBuffer::FlushTo( for (; it != logs_.end(); ++it) { LogBufferElement& element = *it; - state.set_start(element.getSequence()); + state.set_start(element.sequence()); - if (!writer->privileged() && element.getUid() != writer->uid()) { + if (!writer->privileged() && element.uid() != writer->uid()) { continue; } - if (((1 << element.getLogId()) & state.log_mask()) == 0) { + if (((1 << element.log_id()) & state.log_mask()) == 0) { continue; } if (filter) { - FilterResult ret = filter(element.getLogId(), element.getPid(), element.getSequence(), - element.getRealTime(), element.getDropped()); + FilterResult ret = filter(element.log_id(), element.pid(), element.sequence(), + element.realtime(), element.dropped_count()); if (ret == FilterResult::kSkip) { continue; } @@ -179,12 +179,12 @@ bool SimpleLogBuffer::FlushTo( } } - bool same_tid = state.last_tid()[element.getLogId()] == element.getTid(); + bool same_tid = state.last_tid()[element.log_id()] == element.tid(); // Dropped (chatty) immediately following a valid log from the same source in the same log // buffer indicates we have a multiple identical squash. chatty that differs source is due // to spam filter. chatty to chatty of different source is also due to spam filter. - state.last_tid()[element.getLogId()] = - (element.getDropped() && !same_tid) ? 0 : element.getTid(); + state.last_tid()[element.log_id()] = + (element.dropped_count() && !same_tid) ? 0 : element.tid(); shared_lock.unlock(); // We never prune logs equal to or newer than any LogReaderThreads' `start` value, so the @@ -288,22 +288,22 @@ bool SimpleLogBuffer::Prune(log_id_t id, unsigned long prune_rows, uid_t caller_ while (it != logs_.end()) { LogBufferElement& element = *it; - if (element.getLogId() != id) { + if (element.log_id() != id) { ++it; continue; } - if (caller_uid != 0 && element.getUid() != caller_uid) { + if (caller_uid != 0 && element.uid() != caller_uid) { ++it; continue; } - if (oldest && oldest->start() <= element.getSequence()) { + if (oldest && oldest->start() <= element.sequence()) { KickReader(oldest, id, prune_rows); return true; } - stats_->Subtract(&element); + stats_->Subtract(element); it = Erase(it); if (--prune_rows == 0) { return false;