summaryrefslogtreecommitdiff
path: root/logd/LogBufferElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'logd/LogBufferElement.cpp')
-rw-r--r--logd/LogBufferElement.cpp214
1 files changed, 115 insertions, 99 deletions
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index ec81933553..26affa8d47 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "LogBufferElement.h"
+
#include <ctype.h>
#include <endian.h>
#include <fcntl.h>
@@ -22,87 +24,114 @@
#include <time.h>
#include <unistd.h>
+#include <log/log_read.h>
#include <private/android_logger.h>
-#include "LogBuffer.h"
-#include "LogBufferElement.h"
-#include "LogCommand.h"
-#include "LogReader.h"
+#include "LogStatistics.h"
#include "LogUtils.h"
-const log_time LogBufferElement::FLUSH_ERROR((uint32_t)-1, (uint32_t)-1);
-atomic_int_fast64_t LogBufferElement::sequence(1);
-
-LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime,
- uid_t uid, pid_t pid, pid_t tid,
- const char* msg, uint16_t len)
- : mUid(uid),
- mPid(pid),
- mTid(tid),
- mRealTime(realtime),
- mMsgLen(len),
- mLogId(log_id),
- mDropped(false) {
- mMsg = new char[len];
- memcpy(mMsg, msg, len);
+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)
+ : 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),
- 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 {
+ msg_ = new char[msg_len_];
+ memcpy(msg_, elem.msg_, msg_len_);
+ }
+}
+
+LogBufferElement::LogBufferElement(LogBufferElement&& elem) noexcept
+ : 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_ = 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(log_id())) {
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)) {
- return 0;
- }
+ return MsgToTag(msg(), msg_len());
+}
- return reinterpret_cast<const android_event_header_t*>(mMsg)->tag;
+LogStatisticsElement LogBufferElement::ToLogStatisticsElement() const {
+ // Estimate the size of this element in the parent std::list<> by adding two void*'s
+ // corresponding to the next/prev pointers and aligning to 64 bit.
+ uint16_t element_in_list_size =
+ (sizeof(*this) + 2 * sizeof(void*) + sizeof(uint64_t) - 1) & -sizeof(uint64_t);
+ return LogStatisticsElement{
+ .uid = uid(),
+ .pid = pid(),
+ .tid = tid(),
+ .tag = GetTag(),
+ .realtime = realtime(),
+ .msg = msg(),
+ .msg_len = msg_len(),
+ .dropped_count = dropped_count(),
+ .log_id = log_id(),
+ .total_len = static_cast<uint16_t>(element_in_list_size + msg_len()),
+ };
}
-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
@@ -110,7 +139,7 @@ char* android::tidToName(pid_t tid) {
char* retval = nullptr;
char buffer[256];
snprintf(buffer, sizeof(buffer), "/proc/%u/comm", tid);
- int fd = open(buffer, O_RDONLY);
+ int fd = open(buffer, O_RDONLY | O_CLOEXEC);
if (fd >= 0) {
ssize_t ret = read(fd, buffer, sizeof(buffer));
if (ret >= (ssize_t)sizeof(buffer)) {
@@ -150,8 +179,8 @@ char* android::tidToName(pid_t tid) {
return retval;
}
-// assumption: mMsg == NULL
-size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent,
+// assumption: msg_ == NULL
+size_t LogBufferElement::PopulateDroppedMessage(char*& buffer, LogStatistics* stats,
bool lastSame) {
static const char tag[] = "chatty";
@@ -161,17 +190,13 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent
}
static const char format_uid[] = "uid=%u%s%s %s %u line%s";
- parent->wrlock();
- const char* name = parent->uidToName(mUid);
- parent->unlock();
- 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) {
- parent->wrlock();
- commName = parent->pidToName(mPid);
- parent->unlock();
+ commName = stats->PidToName(pid_);
}
if (name && name[0] && commName && (name[0] == commName[0])) {
size_t len = strlen(name + 1);
@@ -187,28 +212,27 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent
}
if (name) {
char* buf = nullptr;
- asprintf(&buf, "(%s)", name);
- if (buf) {
+ int result = asprintf(&buf, "(%s)", name);
+ if (result != -1) {
free(const_cast<char*>(name));
name = buf;
}
}
if (commName) {
char* buf = nullptr;
- asprintf(&buf, " %s", commName);
- if (buf) {
+ int result = asprintf(&buf, " %s", commName);
+ if (result != -1) {
free(const_cast<char*>(commName));
commName = buf;
}
}
// 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(log_id())) {
hdrLen = sizeof(android_log_event_string_t);
} else {
hdrLen = 1 + sizeof(tag);
@@ -222,7 +246,7 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent
}
size_t retval = hdrLen + len;
- if (isBinary()) {
+ if (IsBinary(log_id())) {
android_log_event_string_t* event =
reinterpret_cast<android_log_event_string_t*>(buffer);
@@ -235,45 +259,37 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent
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<char*>(name));
free(const_cast<char*>(commName));
return retval;
}
-log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, bool lastSame) {
+bool LogBufferElement::FlushTo(LogWriter* writer, LogStatistics* stats, bool lastSame) {
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;
-
- struct iovec iovec[2];
- iovec[0].iov_base = &entry;
- iovec[0].iov_len = entry.hdr_size;
+ 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;
-
- if (mDropped) {
- entry.len = populateDroppedMessage(buffer, parent, lastSame);
- if (!entry.len) return mRealTime;
- iovec[1].iov_base = buffer;
+ const char* msg;
+ if (dropped_) {
+ entry.len = PopulateDroppedMessage(buffer, stats, lastSame);
+ if (!entry.len) return true;
+ msg = buffer;
} else {
- entry.len = mMsgLen;
- iovec[1].iov_base = mMsg;
+ msg = msg_;
+ entry.len = msg_len_;
}
- iovec[1].iov_len = entry.len;
- log_time retval = reader->sendDatav(iovec, 1 + (entry.len != 0))
- ? FLUSH_ERROR
- : mRealTime;
+ bool retval = writer->Write(entry, msg);
if (buffer) free(buffer);