LogStatistics.cpp revision 758058ffd8820df71c27db7675c50a90a5fa02b4
134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn/* 234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Copyright (C) 2014 The Android Open Source Project 334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * 434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License"); 534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * you may not use this file except in compliance with the License. 634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * You may obtain a copy of the License at 734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * 834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * http://www.apache.org/licenses/LICENSE-2.0 934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * 1034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Unless required by applicable law or agreed to in writing, software 1134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS, 1234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * See the License for the specific language governing permissions and 1434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * limitations under the License. 1534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn */ 1634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 179a03863e88da99ba010342c874252089dd771f7fMark Salyzyn#include <fcntl.h> 1897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <stdio.h> 1997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <string.h> 2097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <unistd.h> 2134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 2234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <log/logger.h> 2334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 2434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include "LogStatistics.h" 2534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 267718778793b106498b931dd708a466cf3a6f6a0fMark SalyzynLogStatistics::LogStatistics() : enable(false) { 2797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 2897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[id] = 0; 2997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mElements[id] = 0; 3097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizesTotal[id] = 0; 3197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mElementsTotal[id] = 0; 3234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 3334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 3434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 35720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android { 36720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 3797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string 3881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynchar *pidToName(pid_t pid) { 399a03863e88da99ba010342c874252089dd771f7fMark Salyzyn char *retval = NULL; 40ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn if (pid == 0) { // special case from auditd/klogd for kernel 41ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn retval = strdup("logd"); 4297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn } else { 439a03863e88da99ba010342c874252089dd771f7fMark Salyzyn char buffer[512]; 449a03863e88da99ba010342c874252089dd771f7fMark Salyzyn snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid); 459a03863e88da99ba010342c874252089dd771f7fMark Salyzyn int fd = open(buffer, O_RDONLY); 469a03863e88da99ba010342c874252089dd771f7fMark Salyzyn if (fd >= 0) { 479a03863e88da99ba010342c874252089dd771f7fMark Salyzyn ssize_t ret = read(fd, buffer, sizeof(buffer)); 489a03863e88da99ba010342c874252089dd771f7fMark Salyzyn if (ret > 0) { 499a03863e88da99ba010342c874252089dd771f7fMark Salyzyn buffer[sizeof(buffer)-1] = '\0'; 509a03863e88da99ba010342c874252089dd771f7fMark Salyzyn // frameworks intermediate state 51ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn if (fast<strcmp>(buffer, "<pre-initialized>")) { 529a03863e88da99ba010342c874252089dd771f7fMark Salyzyn retval = strdup(buffer); 539a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 549a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 559a03863e88da99ba010342c874252089dd771f7fMark Salyzyn close(fd); 569a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 579a03863e88da99ba010342c874252089dd771f7fMark Salyzyn } 589a03863e88da99ba010342c874252089dd771f7fMark Salyzyn return retval; 599a03863e88da99ba010342c874252089dd771f7fMark Salyzyn} 609a03863e88da99ba010342c874252089dd771f7fMark Salyzyn 61720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 62720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 63758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynvoid LogStatistics::add(LogBufferElement *element) { 64758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t log_id = element->getLogId(); 65758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn unsigned short size = element->getMsgLen(); 6697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[log_id] += size; 6797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn ++mElements[log_id]; 6834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 6997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizesTotal[log_id] += size; 7097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn ++mElementsTotal[log_id]; 71720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 72ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn if (log_id == LOG_ID_KERNEL) { 73ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn return; 74ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn } 75ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn 76758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uidTable[log_id].add(element->getUid(), element); 77ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn 78720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!enable) { 79720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return; 80720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 81720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 82758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable.add(element->getPid(), element); 83758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tidTable.add(element->getTid(), element); 84344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 85758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uint32_t tag = element->getTag(); 86344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn if (tag) { 87758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tagTable.add(tag, element); 88344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 8934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 9034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 91758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynvoid LogStatistics::subtract(LogBufferElement *element) { 92758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t log_id = element->getLogId(); 93758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn unsigned short size = element->getMsgLen(); 9497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn mSizes[log_id] -= size; 9597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn --mElements[log_id]; 9634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 97ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn if (log_id == LOG_ID_KERNEL) { 98ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn return; 99ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn } 100ae4d928d816e30dbe57c2c321b0f0759d0567b3fMark Salyzyn 101758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uidTable[log_id].subtract(element->getUid(), element); 10234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 103720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!enable) { 104720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return; 10534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 10634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 107758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable.subtract(element->getPid(), element); 108758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tidTable.subtract(element->getTid(), element); 109344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 110758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uint32_t tag = element->getTag(); 111344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn if (tag) { 112758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tagTable.subtract(tag, element); 113344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 114c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn} 115c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 116ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// Atomically set an entry to drop 117ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// entry->setDropped(1) must follow this call, caller should do this explicitly. 118758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynvoid LogStatistics::drop(LogBufferElement *element) { 119758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn log_id_t log_id = element->getLogId(); 120758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn unsigned short size = element->getMsgLen(); 121ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn mSizes[log_id] -= size; 122ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 123758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uidTable[log_id].drop(element->getUid(), element); 124ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 125ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn if (!enable) { 126ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn return; 127ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 128ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 129758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable.drop(element->getPid(), element); 130758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn tidTable.drop(element->getTid(), element); 131ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn} 132ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn 13397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn// caller must own and free character string 134758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynconst char *LogStatistics::uidToName(uid_t uid) const { 13597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Local hard coded favourites 13697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (uid == AID_LOGD) { 13797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn return strdup("auditd"); 13834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 13934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 14097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Android hard coded 14197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn const struct android_id_info *info = android_ids; 14234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 14397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn for (size_t i = 0; i < android_id_count; ++i) { 14497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (info->aid == uid) { 14597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn return strdup(info->name); 14634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 14797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn ++info; 14834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 14934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 15008739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn // Parse /data/system/packages.list 151023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn uid_t userId = uid % AID_USER; 152758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *name = android::uidToName(userId); 153023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) { 154023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP)); 155023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn } 15608739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn if (name) { 15708739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn return name; 15808739ba71fc1f2659149be760405d622e5b68f06Mark Salyzyn } 159720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 160720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn // report uid -> pid(s) -> pidToName if unique 161758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn for(pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); ++it) { 162511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn const PidEntry &entry = it->second; 163720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 164720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (entry.getUid() == uid) { 165758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *nameTmp = entry.getName(); 166720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 167758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 168720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (!name) { 169758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = strdup(nameTmp); 170758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } else if (fast<strcmp>(name, nameTmp)) { 171758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn free(const_cast<char *>(name)); 172023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn name = NULL; 173023f51f360472f6bb9bad495e55cdb32b5411bc5Mark Salyzyn break; 174720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 175720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 176720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 177720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 178720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 17997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // No one 180720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn return name; 18134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 18234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 183758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string UidEntry::formatHeader(const std::string &name, log_id_t id) const { 184758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn bool isprune = worstUidEnabledForLogid(id); 185758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(android::base::StringPrintf( 186758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name.c_str(), android_log_id_to_name(id)), 187758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Size"), 188758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string(isprune ? "Pruned" : "")) 189758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn + formatLine(std::string("UID PACKAGE"), 190758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("BYTES"), 191758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string(isprune ? "NUM" : "")); 192758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 193758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 194758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string UidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { 195758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid = getKey(); 196758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name = android::base::StringPrintf("%u", uid); 197758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *nameTmp = stat.uidToName(uid); 198758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 199758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 200758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(6 - name.length(), (size_t)1), 201758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 202758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn free(const_cast<char *>(nameTmp)); 203758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 204758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 205758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string size = android::base::StringPrintf("%zu", getSizes()); 206758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 207758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 208758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t dropped = getDropped(); 209758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (dropped) { 210758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 211758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 212758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 213758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, size, pruned); 214758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 215758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 216758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string PidEntry::formatHeader(const std::string &name, log_id_t /* id */) const { 217758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, 218758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Size"), 219758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Pruned")) 220758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn + formatLine(std::string(" PID/UID COMMAND LINE"), 221758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("BYTES"), 222758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("NUM")); 223758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 224758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 225758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string PidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { 226758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid = getUid(); 227758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name = android::base::StringPrintf("%5u/%u", 228758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getKey(), uid); 229758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *nameTmp = getName(); 230758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 231758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 232758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(12 - name.length(), (size_t)1), 233758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 234758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } else if ((nameTmp = stat.uidToName(uid))) { 235758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 236758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(12 - name.length(), (size_t)1), 237758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 238758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn free(const_cast<char *>(nameTmp)); 239758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 240758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 241758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string size = android::base::StringPrintf("%zu", 242758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getSizes()); 243758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 244758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 245758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t dropped = getDropped(); 246758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (dropped) { 247758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 248758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 249758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 250758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, size, pruned); 251758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 252758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 253758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TidEntry::formatHeader(const std::string &name, log_id_t /* id */) const { 254758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, 255758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Size"), 256758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Pruned")) 257758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn + formatLine(std::string(" TID/UID COMM"), 258758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("BYTES"), 259758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("NUM")); 260758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 261758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 262758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TidEntry::format(const LogStatistics &stat, log_id_t /* id */) const { 263758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid = getUid(); 264758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name = android::base::StringPrintf("%5u/%u", 265758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getKey(), uid); 266758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *nameTmp = getName(); 267758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 268758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 269758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(12 - name.length(), (size_t)1), 270758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 271758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } else if ((nameTmp = stat.uidToName(uid))) { 272758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn // if we do not have a PID name, lets punt to try UID name? 273758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 274758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(12 - name.length(), (size_t)1), 275758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 276758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn free(const_cast<char *>(nameTmp)); 277758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn // We tried, better to not have a name at all, we still 278758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn // have TID/UID by number to report in any case. 279758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 280758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 281758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string size = android::base::StringPrintf("%zu", 282758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getSizes()); 283758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 284758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 285758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn size_t dropped = getDropped(); 286758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (dropped) { 287758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pruned = android::base::StringPrintf("%zu", dropped); 288758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 289758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 290758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, size, pruned); 291758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 292758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 293758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TagEntry::formatHeader(const std::string &name, log_id_t id) const { 294758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn bool isprune = worstUidEnabledForLogid(id); 295758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, 296758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("Size"), 297758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string(isprune ? "Prune" : "")) 298758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn + formatLine(std::string(" TAG/UID TAGNAME"), 299758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string("BYTES"), 300758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string(isprune ? "NUM" : "")); 301758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn} 302758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 303758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string TagEntry::format(const LogStatistics & /* stat */, log_id_t /* id */) const { 304758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name; 305758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn uid_t uid = getUid(); 306758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (uid == (uid_t)-1) { 307758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::base::StringPrintf("%7u", 308758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getKey()); 309ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } else { 310758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = android::base::StringPrintf("%7u/%u", 311758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getKey(), uid); 312ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn } 313758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *nameTmp = getName(); 314758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn if (nameTmp) { 315758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name += android::base::StringPrintf( 316758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "%*s%s", (int)std::max(14 - name.length(), (size_t)1), 317758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn "", nameTmp); 318758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn } 319758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 320758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string size = android::base::StringPrintf("%zu", 321758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn getSizes()); 322758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 323758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string pruned = ""; 324758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 325758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn return formatLine(name, size, pruned); 32634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 32734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 328758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynstd::string LogStatistics::format(uid_t uid, unsigned int logMask) const { 3299a03863e88da99ba010342c874252089dd771f7fMark Salyzyn static const unsigned short spaces_total = 19; 33034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 33197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Report on total logging, current and for all time 33297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn 333decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn std::string output = "size/num"; 33434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t oldLength; 33597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn short spaces = 1; 33634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 33797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 33897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (!(logMask & (1 << id))) { 339c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn continue; 340c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn } 34197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 342c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn if (spaces < 0) { 343c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn spaces = 0; 344c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn } 345decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn output += android::base::StringPrintf("%*s%s", spaces, "", 346decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn android_log_id_to_name(id)); 34797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces += spaces_total + oldLength - output.length(); 34897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn } 349c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 35097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces = 4; 351758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += "\nTotal"; 352c8a576c637ae00577273b778498019dd609fcd15Mark Salyzyn 35397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 35497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (!(logMask & (1 << id))) { 35597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn continue; 35634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 35797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 35897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (spaces < 0) { 35997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces = 0; 360e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn } 361decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", 362decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn sizesTotal(id), 363decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn elementsTotal(id)); 36497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces += spaces_total + oldLength - output.length(); 36534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 36634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 36797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces = 6; 368758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += "\nNow"; 36934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 37097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 37197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (!(logMask & (1 << id))) { 37234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn continue; 37334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 37434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 37597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn size_t els = elements(id); 37634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn if (els) { 37797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn oldLength = output.length(); 378e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn if (spaces < 0) { 379e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn spaces = 0; 380e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn } 381decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", 382decbcd9c418a4d076965971e74fd51fab497414bMark Salyzyn sizes(id), els); 38397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn spaces -= output.length() - oldLength; 38434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 38534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn spaces += spaces_total; 38634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 38734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 38897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Report on Chattiest 3898e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn 390758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn std::string name; 391758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn 39297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn // Chattiest by application (UID) 39397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn log_id_for_each(id) { 39497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (!(logMask & (1 << id))) { 3958e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn continue; 3968e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn } 3978e72c5384b288bc11af60e12686a44e502633e3dMark Salyzyn 398758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = (uid == AID_ROOT) 399758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn ? "Chattiest UIDs in %s log buffer:" 400758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn : "Logging for your UID in %s log buffer:"; 401758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += uidTable[id].format(*this, uid, name, id); 402720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 40397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn 404720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn if (enable) { 405758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = (uid == AID_ROOT) ? "Chattiest PIDs:" : "Logging for this PID:"; 406758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += pidTable.format(*this, uid, name); 407758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = "Chattiest TIDs:"; 408758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += tidTable.format(*this, uid, name); 40917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn } 41017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn 411344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn if (enable && (logMask & (1 << LOG_ID_EVENTS))) { 412758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn name = "Chattiest events log buffer TAGs:"; 413758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn output += tagTable.format(*this, uid, name, LOG_ID_EVENTS); 414344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn } 415344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn 41673160acc5cb5236b30327569e6b51dbfe73e4a0fMark Salyzyn return output; 41734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn} 4184ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn 419720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynnamespace android { 420720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 421720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t pidToUid(pid_t pid) { 42297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn char buffer[512]; 42397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid); 42497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn FILE *fp = fopen(buffer, "r"); 42597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn if (fp) { 42697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn while (fgets(buffer, sizeof(buffer), fp)) { 42797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn int uid; 428c32afdf913f082235b1e66f5a57678c7f0723129Mark Salyzyn if (sscanf(buffer, "Uid: %d", &uid) == 1) { 42997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn fclose(fp); 43097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn return uid; 4314ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 4324ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 43397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn fclose(fp); 4344ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn } 435e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn return AID_LOGD; // associate this with the logger 4364ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn} 437720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 438720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 439720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 440720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynuid_t LogStatistics::pidToUid(pid_t pid) { 441511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn return pidTable.add(pid)->second.getUid(); 442720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 443720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn 444720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn// caller must free character string 445758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynconst char *LogStatistics::pidToName(pid_t pid) const { 446758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn // An inconvenient truth ... getName() can alter the object 447758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn pidTable_t &writablePidTable = const_cast<pidTable_t &>(pidTable); 448758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn const char *name = writablePidTable.add(pid)->second.getName(); 44981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn if (!name) { 45081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn return NULL; 451720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn } 45281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn return strdup(name); 453720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn} 454