summaryrefslogtreecommitdiffstats
path: root/logd
diff options
context:
space:
mode:
authorMark Salyzyn <salyzyn@google.com>2015-04-20 13:35:15 -0700
committerMark Salyzyn <salyzyn@google.com>2015-05-13 09:23:01 -0700
commit654904f0f9c42458cae2b1931265f97f8fb6cb95 (patch)
tree9c6e749b9f0cd6ac1eaff346cf0e5fddd458235c /logd
parent66091f11f427587bf810d89b0f64be556e1cd168 (diff)
downloadsystem_core-654904f0f9c42458cae2b1931265f97f8fb6cb95.zip
system_core-654904f0f9c42458cae2b1931265f97f8fb6cb95.tar.gz
system_core-654904f0f9c42458cae2b1931265f97f8fb6cb95.tar.bz2
logd: Add TID statistics
(cherry pick from commit 17ed6797df722464eb5cc6dfc3e1e32aec284b70) Bug: 19608965 Change-Id: Ifbf0b00c48ef12b5970b9f9f217bd1dd8f587f2c
Diffstat (limited to 'logd')
-rw-r--r--logd/LogBufferElement.cpp6
-rw-r--r--logd/LogBufferElement.h1
-rw-r--r--logd/LogStatistics.cpp60
-rw-r--r--logd/LogStatistics.h56
4 files changed, 120 insertions, 3 deletions
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index f98d5cd..3d7237e 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -58,7 +58,7 @@ uint32_t LogBufferElement::getTag() const {
}
// caller must own and free character string
-static char *tidToName(pid_t tid) {
+char *android::tidToName(pid_t tid) {
char *retval = NULL;
char buffer[256];
snprintf(buffer, sizeof(buffer), "/proc/%u/comm", tid);
@@ -108,9 +108,9 @@ size_t LogBufferElement::populateDroppedMessage(char *&buffer,
static const char format_uid[] = "uid=%u%s too chatty%s, expire %u line%s";
char *name = parent->uidToName(mUid);
- char *commName = tidToName(mTid);
+ char *commName = android::tidToName(mTid);
if (!commName && (mTid != mPid)) {
- commName = tidToName(mPid);
+ commName = android::tidToName(mPid);
}
if (!commName) {
commName = parent->pidToName(mPid);
diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h
index bca3043..5dabaac 100644
--- a/logd/LogBufferElement.h
+++ b/logd/LogBufferElement.h
@@ -35,6 +35,7 @@ char *uidToName(uid_t uid);
// Furnished in LogStatistics.cpp. Caller must own and free returned value
char *pidToName(pid_t pid);
+char *tidToName(pid_t tid);
// Furnished in main.cpp. Thread safe.
const char *tagToName(uint32_t tag);
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 675b692..90c49c0 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -83,6 +83,7 @@ void LogStatistics::add(LogBufferElement *e) {
}
pidTable.add(e->getPid(), e);
+ tidTable.add(e->getTid(), e);
uint32_t tag = e->getTag();
if (tag) {
@@ -107,6 +108,7 @@ void LogStatistics::subtract(LogBufferElement *e) {
}
pidTable.subtract(e->getPid(), e);
+ tidTable.subtract(e->getTid(), e);
uint32_t tag = e->getTag();
if (tag) {
@@ -128,6 +130,7 @@ void LogStatistics::drop(LogBufferElement *e) {
}
pidTable.drop(e->getPid(), e);
+ tidTable.drop(e->getTid(), e);
}
// caller must own and free character string
@@ -390,6 +393,63 @@ void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
}
}
+ if (enable) {
+ // Tid table
+ bool headerPrinted = false;
+ // sort() returns list of references, unique_ptr makes sure self-delete
+ std::unique_ptr<const TidEntry *[]> sorted = tidTable.sort(maximum_sorted_entries);
+ ssize_t index = -1;
+ while ((index = tidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
+ const TidEntry *entry = sorted[index];
+ uid_t u = entry->getUid();
+ if ((uid != AID_ROOT) && (u != uid)) {
+ continue;
+ }
+
+ if (!headerPrinted) { // Only print header if we have table to print
+ output.appendFormat("\n\n");
+ android::String8 name("Chattiest TIDs:");
+ android::String8 size("Size");
+ android::String8 pruned("Pruned");
+ format_line(output, name, size, pruned);
+
+ name.setTo(" TID/UID COMM");
+ size.setTo("BYTES");
+ pruned.setTo("LINES");
+ format_line(output, name, size, pruned);
+
+ headerPrinted = true;
+ }
+
+ android::String8 name("");
+ name.appendFormat("%5u/%u", entry->getKey(), u);
+ const char *n = entry->getName();
+ if (n) {
+ name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", n);
+ } else {
+ // if we do not have a PID name, lets punt to try UID name?
+ char *un = uidToName(u);
+ if (un) {
+ name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", un);
+ free(un);
+ }
+ // We tried, better to not have a name at all, we still
+ // have TID/UID by number to report in any case.
+ }
+
+ android::String8 size("");
+ size.appendFormat("%zu", entry->getSizes());
+
+ android::String8 pruned("");
+ size_t dropped = entry->getDropped();
+ if (dropped) {
+ pruned.appendFormat("%zu", dropped);
+ }
+
+ format_line(output, name, size, pruned);
+ }
+ }
+
if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
// Tag table
bool headerPrinted = false;
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index d21a75b..f60f3ed 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -209,6 +209,58 @@ struct PidEntry : public EntryBaseDropped {
}
};
+struct TidEntry : public EntryBaseDropped {
+ const pid_t tid;
+ uid_t uid;
+ char *name;
+
+ TidEntry(pid_t t):
+ EntryBaseDropped(),
+ tid(t),
+ uid(android::pidToUid(t)),
+ name(android::tidToName(tid)) { }
+ TidEntry(LogBufferElement *e):
+ EntryBaseDropped(e),
+ tid(e->getTid()),
+ uid(e->getUid()),
+ name(android::tidToName(e->getTid())) { }
+ TidEntry(const TidEntry &c):
+ EntryBaseDropped(c),
+ tid(c.tid),
+ uid(c.uid),
+ name(c.name ? strdup(c.name) : NULL) { }
+ ~TidEntry() { free(name); }
+
+ const pid_t&getKey() const { return tid; }
+ const uid_t&getUid() const { return uid; }
+ const char*getName() const { return name; }
+
+ inline void add(pid_t t) {
+ if (name && !strncmp(name, "zygote", 6)) {
+ free(name);
+ name = NULL;
+ }
+ if (!name) {
+ char *n = android::tidToName(t);
+ if (n) {
+ name = n;
+ }
+ }
+ }
+
+ inline void add(LogBufferElement *e) {
+ uid_t u = e->getUid();
+ if (getUid() != u) {
+ uid = u;
+ free(name);
+ name = android::tidToName(e->getTid());
+ } else {
+ add(e->getTid());
+ }
+ EntryBaseDropped::add(e);
+ }
+};
+
struct TagEntry : public EntryBase {
const uint32_t tag;
uid_t uid;
@@ -247,6 +299,10 @@ class LogStatistics {
typedef LogHashtable<pid_t, PidEntry> pidTable_t;
pidTable_t pidTable;
+ // tid to uid list
+ typedef LogHashtable<pid_t, TidEntry> tidTable_t;
+ tidTable_t tidTable;
+
// tag list
typedef LogHashtable<uint32_t, TagEntry> tagTable_t;
tagTable_t tagTable;