| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2014 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
| Mark Salyzyn | c4e4823 | 2017-05-04 13:54:46 -0700 | [diff] [blame] | 17 | #include <ctype.h> | 
| Mark Salyzyn | 9a03863 | 2014-04-07 07:05:40 -0700 | [diff] [blame] | 18 | #include <fcntl.h> | 
| Mark Salyzyn | 02dd2f4 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 19 | #include <inttypes.h> | 
| Mark Salyzyn | b8a95bd | 2016-04-07 11:06:31 -0700 | [diff] [blame] | 20 | #include <pwd.h> | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 21 | #include <stdio.h> | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 22 | #include <string.h> | 
| Mark Salyzyn | b8a95bd | 2016-04-07 11:06:31 -0700 | [diff] [blame] | 23 | #include <sys/types.h> | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 24 | #include <unistd.h> | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 25 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 26 | #include <list> | 
|  | 27 |  | 
| Mark Salyzyn | 03bb759 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 28 | #include <private/android_logger.h> | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 29 |  | 
|  | 30 | #include "LogStatistics.h" | 
|  | 31 |  | 
| Mark Salyzyn | 03bb759 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 32 | static const uint64_t hourSec = 60 * 60; | 
|  | 33 | static const uint64_t monthSec = 31 * 24 * hourSec; | 
|  | 34 |  | 
| Mark Salyzyn | 3296291 | 2016-09-12 10:29:17 -0700 | [diff] [blame] | 35 | size_t LogStatistics::SizesTotal; | 
|  | 36 |  | 
| Mark Salyzyn | 7718778 | 2015-05-12 15:21:31 -0700 | [diff] [blame] | 37 | LogStatistics::LogStatistics() : enable(false) { | 
| Mark Salyzyn | 03bb759 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 38 | log_time now(CLOCK_REALTIME); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 39 | log_id_for_each(id) { | 
|  | 40 | mSizes[id] = 0; | 
|  | 41 | mElements[id] = 0; | 
| Mark Salyzyn | 58b8be8 | 2015-09-30 07:40:09 -0700 | [diff] [blame] | 42 | mDroppedElements[id] = 0; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 43 | mSizesTotal[id] = 0; | 
|  | 44 | mElementsTotal[id] = 0; | 
| Mark Salyzyn | 03bb759 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 45 | mOldest[id] = now; | 
|  | 46 | mNewest[id] = now; | 
|  | 47 | mNewestDropped[id] = now; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 48 | } | 
|  | 49 | } | 
|  | 50 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 51 | namespace android { | 
|  | 52 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 53 | size_t sizesTotal() { | 
|  | 54 | return LogStatistics::sizesTotal(); | 
|  | 55 | } | 
| Mark Salyzyn | 3296291 | 2016-09-12 10:29:17 -0700 | [diff] [blame] | 56 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 57 | // caller must own and free character string | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 58 | char* pidToName(pid_t pid) { | 
| Yi Kong | c8d09dd | 2018-07-13 17:39:22 -0700 | [diff] [blame] | 59 | char* retval = nullptr; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 60 | if (pid == 0) {  // special case from auditd/klogd for kernel | 
| Mark Salyzyn | ae4d928 | 2014-10-15 08:49:39 -0700 | [diff] [blame] | 61 | retval = strdup("logd"); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 62 | } else { | 
| Mark Salyzyn | 9a03863 | 2014-04-07 07:05:40 -0700 | [diff] [blame] | 63 | char buffer[512]; | 
|  | 64 | snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid); | 
|  | 65 | int fd = open(buffer, O_RDONLY); | 
|  | 66 | if (fd >= 0) { | 
|  | 67 | ssize_t ret = read(fd, buffer, sizeof(buffer)); | 
|  | 68 | if (ret > 0) { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 69 | buffer[sizeof(buffer) - 1] = '\0'; | 
| Mark Salyzyn | 9a03863 | 2014-04-07 07:05:40 -0700 | [diff] [blame] | 70 | // frameworks intermediate state | 
| Mark Salyzyn | 0eeb06b | 2016-12-02 10:08:48 -0800 | [diff] [blame] | 71 | if (fastcmp<strcmp>(buffer, "<pre-initialized>")) { | 
| Mark Salyzyn | 9a03863 | 2014-04-07 07:05:40 -0700 | [diff] [blame] | 72 | retval = strdup(buffer); | 
|  | 73 | } | 
|  | 74 | } | 
|  | 75 | close(fd); | 
|  | 76 | } | 
|  | 77 | } | 
|  | 78 | return retval; | 
|  | 79 | } | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 80 | } | 
|  | 81 |  | 
| Mark Salyzyn | 02dd2f4 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 82 | void LogStatistics::addTotal(LogBufferElement* element) { | 
|  | 83 | if (element->getDropped()) return; | 
|  | 84 |  | 
|  | 85 | log_id_t log_id = element->getLogId(); | 
| Chih-Hung Hsieh | 08d470b | 2018-08-13 14:22:56 -0700 | [diff] [blame] | 86 | uint16_t size = element->getMsgLen(); | 
| Mark Salyzyn | 02dd2f4 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 87 | mSizesTotal[log_id] += size; | 
|  | 88 | SizesTotal += size; | 
|  | 89 | ++mElementsTotal[log_id]; | 
|  | 90 | } | 
|  | 91 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 92 | void LogStatistics::add(LogBufferElement* element) { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 93 | log_id_t log_id = element->getLogId(); | 
| Chih-Hung Hsieh | 08d470b | 2018-08-13 14:22:56 -0700 | [diff] [blame] | 94 | uint16_t size = element->getMsgLen(); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 95 | mSizes[log_id] += size; | 
|  | 96 | ++mElements[log_id]; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 97 |  | 
| Mark Salyzyn | 02dd2f4 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 98 | // When caller adding a chatty entry, they will have already | 
|  | 99 | // called add() and subtract() for each entry as they are | 
|  | 100 | // evaluated and trimmed, thus recording size and number of | 
|  | 101 | // elements, but we must recognize the manufactured dropped | 
|  | 102 | // entry as not contributing to the lifetime totals. | 
| Mark Salyzyn | a2c0222 | 2016-12-13 10:31:29 -0800 | [diff] [blame] | 103 | if (element->getDropped()) { | 
|  | 104 | ++mDroppedElements[log_id]; | 
|  | 105 | } else { | 
| Mark Salyzyn | a2c0222 | 2016-12-13 10:31:29 -0800 | [diff] [blame] | 106 | mSizesTotal[log_id] += size; | 
| Mark Salyzyn | 3296291 | 2016-09-12 10:29:17 -0700 | [diff] [blame] | 107 | SizesTotal += size; | 
| Mark Salyzyn | a2c0222 | 2016-12-13 10:31:29 -0800 | [diff] [blame] | 108 | ++mElementsTotal[log_id]; | 
|  | 109 | } | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 110 |  | 
| Mark Salyzyn | 03bb759 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 111 | log_time stamp(element->getRealTime()); | 
|  | 112 | if (mNewest[log_id] < stamp) { | 
|  | 113 | // A major time update invalidates the statistics :-( | 
|  | 114 | log_time diff = stamp - mNewest[log_id]; | 
|  | 115 | mNewest[log_id] = stamp; | 
|  | 116 |  | 
|  | 117 | if (diff.tv_sec > hourSec) { | 
|  | 118 | // approximate Do-Your-Best fixup | 
|  | 119 | diff += mOldest[log_id]; | 
|  | 120 | if ((diff > stamp) && ((diff - stamp).tv_sec < hourSec)) { | 
|  | 121 | diff = stamp; | 
|  | 122 | } | 
|  | 123 | if (diff <= stamp) { | 
|  | 124 | mOldest[log_id] = diff; | 
|  | 125 | if (mNewestDropped[log_id] < diff) { | 
|  | 126 | mNewestDropped[log_id] = diff; | 
|  | 127 | } | 
|  | 128 | } | 
|  | 129 | } | 
|  | 130 | } | 
|  | 131 |  | 
| Mark Salyzyn | ae4d928 | 2014-10-15 08:49:39 -0700 | [diff] [blame] | 132 | if (log_id == LOG_ID_KERNEL) { | 
|  | 133 | return; | 
|  | 134 | } | 
|  | 135 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 136 | uidTable[log_id].add(element->getUid(), element); | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 137 | if (element->getUid() == AID_SYSTEM) { | 
|  | 138 | pidSystemTable[log_id].add(element->getPid(), element); | 
|  | 139 | } | 
| Mark Salyzyn | ae4d928 | 2014-10-15 08:49:39 -0700 | [diff] [blame] | 140 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 141 | if (!enable) { | 
|  | 142 | return; | 
|  | 143 | } | 
|  | 144 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 145 | pidTable.add(element->getPid(), element); | 
|  | 146 | tidTable.add(element->getTid(), element); | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 147 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 148 | uint32_t tag = element->getTag(); | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 149 | if (tag) { | 
| Mark Salyzyn | 083b037 | 2015-12-04 10:59:45 -0800 | [diff] [blame] | 150 | if (log_id == LOG_ID_SECURITY) { | 
|  | 151 | securityTagTable.add(tag, element); | 
|  | 152 | } else { | 
|  | 153 | tagTable.add(tag, element); | 
|  | 154 | } | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 155 | } | 
| Mark Salyzyn | f99a7d6 | 2017-04-19 14:39:21 -0700 | [diff] [blame] | 156 |  | 
|  | 157 | if (!element->getDropped()) { | 
|  | 158 | tagNameTable.add(TagNameKey(element), element); | 
|  | 159 | } | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 160 | } | 
|  | 161 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 162 | void LogStatistics::subtract(LogBufferElement* element) { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 163 | log_id_t log_id = element->getLogId(); | 
| Chih-Hung Hsieh | 08d470b | 2018-08-13 14:22:56 -0700 | [diff] [blame] | 164 | uint16_t size = element->getMsgLen(); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 165 | mSizes[log_id] -= size; | 
|  | 166 | --mElements[log_id]; | 
| Mark Salyzyn | 58b8be8 | 2015-09-30 07:40:09 -0700 | [diff] [blame] | 167 | if (element->getDropped()) { | 
|  | 168 | --mDroppedElements[log_id]; | 
|  | 169 | } | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 170 |  | 
| Mark Salyzyn | 03bb759 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 171 | if (mOldest[log_id] < element->getRealTime()) { | 
|  | 172 | mOldest[log_id] = element->getRealTime(); | 
|  | 173 | } | 
|  | 174 |  | 
| Mark Salyzyn | ae4d928 | 2014-10-15 08:49:39 -0700 | [diff] [blame] | 175 | if (log_id == LOG_ID_KERNEL) { | 
|  | 176 | return; | 
|  | 177 | } | 
|  | 178 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 179 | uidTable[log_id].subtract(element->getUid(), element); | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 180 | if (element->getUid() == AID_SYSTEM) { | 
|  | 181 | pidSystemTable[log_id].subtract(element->getPid(), element); | 
|  | 182 | } | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 183 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 184 | if (!enable) { | 
|  | 185 | return; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 186 | } | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 187 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 188 | pidTable.subtract(element->getPid(), element); | 
|  | 189 | tidTable.subtract(element->getTid(), element); | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 190 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 191 | uint32_t tag = element->getTag(); | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 192 | if (tag) { | 
| Mark Salyzyn | 083b037 | 2015-12-04 10:59:45 -0800 | [diff] [blame] | 193 | if (log_id == LOG_ID_SECURITY) { | 
|  | 194 | securityTagTable.subtract(tag, element); | 
|  | 195 | } else { | 
|  | 196 | tagTable.subtract(tag, element); | 
|  | 197 | } | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 198 | } | 
| Mark Salyzyn | f99a7d6 | 2017-04-19 14:39:21 -0700 | [diff] [blame] | 199 |  | 
|  | 200 | if (!element->getDropped()) { | 
|  | 201 | tagNameTable.subtract(TagNameKey(element), element); | 
|  | 202 | } | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 203 | } | 
|  | 204 |  | 
| Mark Salyzyn | ab0dcf6 | 2015-03-16 12:04:09 -0700 | [diff] [blame] | 205 | // Atomically set an entry to drop | 
|  | 206 | // entry->setDropped(1) must follow this call, caller should do this explicitly. | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 207 | void LogStatistics::drop(LogBufferElement* element) { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 208 | log_id_t log_id = element->getLogId(); | 
| Chih-Hung Hsieh | 08d470b | 2018-08-13 14:22:56 -0700 | [diff] [blame] | 209 | uint16_t size = element->getMsgLen(); | 
| Mark Salyzyn | ab0dcf6 | 2015-03-16 12:04:09 -0700 | [diff] [blame] | 210 | mSizes[log_id] -= size; | 
| Mark Salyzyn | 58b8be8 | 2015-09-30 07:40:09 -0700 | [diff] [blame] | 211 | ++mDroppedElements[log_id]; | 
| Mark Salyzyn | ab0dcf6 | 2015-03-16 12:04:09 -0700 | [diff] [blame] | 212 |  | 
| Mark Salyzyn | 03bb759 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 213 | if (mNewestDropped[log_id] < element->getRealTime()) { | 
|  | 214 | mNewestDropped[log_id] = element->getRealTime(); | 
|  | 215 | } | 
|  | 216 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 217 | uidTable[log_id].drop(element->getUid(), element); | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 218 | if (element->getUid() == AID_SYSTEM) { | 
|  | 219 | pidSystemTable[log_id].drop(element->getPid(), element); | 
|  | 220 | } | 
| Mark Salyzyn | ab0dcf6 | 2015-03-16 12:04:09 -0700 | [diff] [blame] | 221 |  | 
|  | 222 | if (!enable) { | 
|  | 223 | return; | 
|  | 224 | } | 
|  | 225 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 226 | pidTable.drop(element->getPid(), element); | 
|  | 227 | tidTable.drop(element->getTid(), element); | 
| Mark Salyzyn | 6a06694 | 2016-07-14 15:34:30 -0700 | [diff] [blame] | 228 |  | 
|  | 229 | uint32_t tag = element->getTag(); | 
|  | 230 | if (tag) { | 
|  | 231 | if (log_id == LOG_ID_SECURITY) { | 
|  | 232 | securityTagTable.drop(tag, element); | 
|  | 233 | } else { | 
|  | 234 | tagTable.drop(tag, element); | 
|  | 235 | } | 
|  | 236 | } | 
| Mark Salyzyn | f99a7d6 | 2017-04-19 14:39:21 -0700 | [diff] [blame] | 237 |  | 
|  | 238 | tagNameTable.subtract(TagNameKey(element), element); | 
| Mark Salyzyn | ab0dcf6 | 2015-03-16 12:04:09 -0700 | [diff] [blame] | 239 | } | 
|  | 240 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 241 | // caller must own and free character string | 
| Mark Salyzyn | 3c501b5 | 2017-04-18 14:09:45 -0700 | [diff] [blame] | 242 | // Requires parent LogBuffer::wrlock() to be held | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 243 | const char* LogStatistics::uidToName(uid_t uid) const { | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 244 | // Local hard coded favourites | 
|  | 245 | if (uid == AID_LOGD) { | 
|  | 246 | return strdup("auditd"); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 247 | } | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 248 |  | 
| Mark Salyzyn | b8a95bd | 2016-04-07 11:06:31 -0700 | [diff] [blame] | 249 | // Android system | 
|  | 250 | if (uid < AID_APP) { | 
|  | 251 | // in bionic, thread safe as long as we copy the results | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 252 | struct passwd* pwd = getpwuid(uid); | 
| Mark Salyzyn | b8a95bd | 2016-04-07 11:06:31 -0700 | [diff] [blame] | 253 | if (pwd) { | 
|  | 254 | return strdup(pwd->pw_name); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 255 | } | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 256 | } | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 257 |  | 
| Mark Salyzyn | 08739ba | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 258 | // Parse /data/system/packages.list | 
| Jeff Sharkey | dff4470 | 2016-12-13 11:55:19 -0700 | [diff] [blame] | 259 | uid_t userId = uid % AID_USER_OFFSET; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 260 | const char* name = android::uidToName(userId); | 
| Mark Salyzyn | 023f51f | 2015-04-29 12:48:45 -0700 | [diff] [blame] | 261 | if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) { | 
|  | 262 | name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP)); | 
|  | 263 | } | 
| Mark Salyzyn | 08739ba | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 264 | if (name) { | 
|  | 265 | return name; | 
|  | 266 | } | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 267 |  | 
| Mark Salyzyn | b8a95bd | 2016-04-07 11:06:31 -0700 | [diff] [blame] | 268 | // Android application | 
|  | 269 | if (uid >= AID_APP) { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 270 | struct passwd* pwd = getpwuid(uid); | 
| Mark Salyzyn | b8a95bd | 2016-04-07 11:06:31 -0700 | [diff] [blame] | 271 | if (pwd) { | 
|  | 272 | return strdup(pwd->pw_name); | 
|  | 273 | } | 
|  | 274 | } | 
|  | 275 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 276 | // report uid -> pid(s) -> pidToName if unique | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 277 | for (pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); | 
|  | 278 | ++it) { | 
|  | 279 | const PidEntry& entry = it->second; | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 280 |  | 
|  | 281 | if (entry.getUid() == uid) { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 282 | const char* nameTmp = entry.getName(); | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 283 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 284 | if (nameTmp) { | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 285 | if (!name) { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 286 | name = strdup(nameTmp); | 
| Mark Salyzyn | 0eeb06b | 2016-12-02 10:08:48 -0800 | [diff] [blame] | 287 | } else if (fastcmp<strcmp>(name, nameTmp)) { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 288 | free(const_cast<char*>(name)); | 
| Yi Kong | c8d09dd | 2018-07-13 17:39:22 -0700 | [diff] [blame] | 289 | name = nullptr; | 
| Mark Salyzyn | 023f51f | 2015-04-29 12:48:45 -0700 | [diff] [blame] | 290 | break; | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 291 | } | 
|  | 292 | } | 
|  | 293 | } | 
|  | 294 | } | 
|  | 295 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 296 | // No one | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 297 | return name; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 298 | } | 
|  | 299 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 300 | std::string UidEntry::formatHeader(const std::string& name, log_id_t id) const { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 301 | bool isprune = worstUidEnabledForLogid(id); | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 302 | return formatLine(android::base::StringPrintf(name.c_str(), | 
|  | 303 | android_log_id_to_name(id)), | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 304 | std::string("Size"), | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 305 | std::string(isprune ? "+/-  Pruned" : "")) + | 
|  | 306 | formatLine(std::string("UID   PACKAGE"), std::string("BYTES"), | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 307 | std::string(isprune ? "NUM" : "")); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 308 | } | 
|  | 309 |  | 
| Mark Salyzyn | f31ae3d | 2017-04-13 15:35:22 -0700 | [diff] [blame] | 310 | // Helper to truncate name, if too long, and add name dressings | 
|  | 311 | static void formatTmp(const LogStatistics& stat, const char* nameTmp, uid_t uid, | 
|  | 312 | std::string& name, std::string& size, size_t nameLen) { | 
|  | 313 | const char* allocNameTmp = nullptr; | 
|  | 314 | if (!nameTmp) nameTmp = allocNameTmp = stat.uidToName(uid); | 
|  | 315 | if (nameTmp) { | 
|  | 316 | size_t lenSpace = std::max(nameLen - name.length(), (size_t)1); | 
|  | 317 | size_t len = EntryBaseConstants::total_len - | 
|  | 318 | EntryBaseConstants::pruned_len - size.length() - | 
|  | 319 | name.length() - lenSpace - 2; | 
|  | 320 | size_t lenNameTmp = strlen(nameTmp); | 
|  | 321 | while ((len < lenNameTmp) && (lenSpace > 1)) { | 
|  | 322 | ++len; | 
|  | 323 | --lenSpace; | 
|  | 324 | } | 
|  | 325 | name += android::base::StringPrintf("%*s", (int)lenSpace, ""); | 
|  | 326 | if (len < lenNameTmp) { | 
|  | 327 | name += "..."; | 
|  | 328 | nameTmp += lenNameTmp - std::max(len - 3, (size_t)1); | 
|  | 329 | } | 
|  | 330 | name += nameTmp; | 
|  | 331 | free(const_cast<char*>(allocNameTmp)); | 
|  | 332 | } | 
|  | 333 | } | 
|  | 334 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 335 | std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const { | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 336 | uid_t uid = getUid(); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 337 | std::string name = android::base::StringPrintf("%u", uid); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 338 | std::string size = android::base::StringPrintf("%zu", getSizes()); | 
|  | 339 |  | 
| Mark Salyzyn | f31ae3d | 2017-04-13 15:35:22 -0700 | [diff] [blame] | 340 | formatTmp(stat, nullptr, uid, name, size, 6); | 
|  | 341 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 342 | std::string pruned = ""; | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 343 | if (worstUidEnabledForLogid(id)) { | 
|  | 344 | size_t totalDropped = 0; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 345 | for (LogStatistics::uidTable_t::const_iterator it = | 
|  | 346 | stat.uidTable[id].begin(); | 
|  | 347 | it != stat.uidTable[id].end(); ++it) { | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 348 | totalDropped += it->second.getDropped(); | 
|  | 349 | } | 
|  | 350 | size_t sizes = stat.sizes(id); | 
|  | 351 | size_t totalSize = stat.sizesTotal(id); | 
|  | 352 | size_t totalElements = stat.elementsTotal(id); | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 353 | float totalVirtualSize = | 
|  | 354 | (float)sizes + (float)totalDropped * totalSize / totalElements; | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 355 | size_t entrySize = getSizes(); | 
|  | 356 | float virtualEntrySize = entrySize; | 
|  | 357 | int realPermille = virtualEntrySize * 1000.0 / sizes; | 
|  | 358 | size_t dropped = getDropped(); | 
|  | 359 | if (dropped) { | 
|  | 360 | pruned = android::base::StringPrintf("%zu", dropped); | 
|  | 361 | virtualEntrySize += (float)dropped * totalSize / totalElements; | 
|  | 362 | } | 
|  | 363 | int virtualPermille = virtualEntrySize * 1000.0 / totalVirtualSize; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 364 | int permille = | 
|  | 365 | (realPermille - virtualPermille) * 1000L / (virtualPermille ?: 1); | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 366 | if ((permille < -1) || (1 < permille)) { | 
|  | 367 | std::string change; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 368 | const char* units = "%"; | 
|  | 369 | const char* prefix = (permille > 0) ? "+" : ""; | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 370 |  | 
|  | 371 | if (permille > 999) { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 372 | permille = (permille + 1000) / 100;  // Now tenths fold | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 373 | units = "X"; | 
|  | 374 | prefix = ""; | 
|  | 375 | } | 
|  | 376 | if ((-99 < permille) && (permille < 99)) { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 377 | change = android::base::StringPrintf( | 
|  | 378 | "%s%d.%u%s", prefix, permille / 10, | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 379 | ((permille < 0) ? (-permille % 10) : (permille % 10)), | 
|  | 380 | units); | 
|  | 381 | } else { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 382 | change = android::base::StringPrintf( | 
|  | 383 | "%s%d%s", prefix, (permille + 5) / 10, units); | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 384 | } | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 385 | ssize_t spaces = EntryBaseConstants::pruned_len - 2 - | 
|  | 386 | pruned.length() - change.length(); | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 387 | if ((spaces <= 0) && pruned.length()) { | 
|  | 388 | spaces = 1; | 
|  | 389 | } | 
| Mark Salyzyn | d966e22 | 2016-12-19 22:23:03 +0000 | [diff] [blame] | 390 | if (spaces > 0) { | 
| Mark Salyzyn | c723df8 | 2015-08-24 11:08:00 -0700 | [diff] [blame] | 391 | change += android::base::StringPrintf("%*s", (int)spaces, ""); | 
|  | 392 | } | 
|  | 393 | pruned = change + pruned; | 
|  | 394 | } | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 395 | } | 
|  | 396 |  | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 397 | std::string output = formatLine(name, size, pruned); | 
|  | 398 |  | 
|  | 399 | if (uid != AID_SYSTEM) { | 
|  | 400 | return output; | 
|  | 401 | } | 
|  | 402 |  | 
|  | 403 | static const size_t maximum_sorted_entries = 32; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 404 | std::unique_ptr<const PidEntry* []> sorted = | 
|  | 405 | stat.pidSystemTable[id].sort(uid, (pid_t)0, maximum_sorted_entries); | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 406 |  | 
|  | 407 | if (!sorted.get()) { | 
|  | 408 | return output; | 
|  | 409 | } | 
|  | 410 | std::string byPid; | 
|  | 411 | size_t index; | 
|  | 412 | bool hasDropped = false; | 
|  | 413 | for (index = 0; index < maximum_sorted_entries; ++index) { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 414 | const PidEntry* entry = sorted[index]; | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 415 | if (!entry) { | 
|  | 416 | break; | 
|  | 417 | } | 
|  | 418 | if (entry->getSizes() <= (getSizes() / 100)) { | 
|  | 419 | break; | 
|  | 420 | } | 
|  | 421 | if (entry->getDropped()) { | 
|  | 422 | hasDropped = true; | 
|  | 423 | } | 
|  | 424 | byPid += entry->format(stat, id); | 
|  | 425 | } | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 426 | if (index > 1) {  // print this only if interesting | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 427 | std::string ditto("\" "); | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 428 | output += formatLine(std::string("  PID/UID   COMMAND LINE"), ditto, | 
|  | 429 | hasDropped ? ditto : std::string("")); | 
| Mark Salyzyn | bec3c3d | 2015-08-28 08:02:59 -0700 | [diff] [blame] | 430 | output += byPid; | 
|  | 431 | } | 
|  | 432 |  | 
|  | 433 | return output; | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 434 | } | 
|  | 435 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 436 | std::string PidEntry::formatHeader(const std::string& name, | 
|  | 437 | log_id_t /* id */) const { | 
|  | 438 | return formatLine(name, std::string("Size"), std::string("Pruned")) + | 
|  | 439 | formatLine(std::string("  PID/UID   COMMAND LINE"), | 
|  | 440 | std::string("BYTES"), std::string("NUM")); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 441 | } | 
|  | 442 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 443 | std::string PidEntry::format(const LogStatistics& stat, | 
|  | 444 | log_id_t /* id */) const { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 445 | uid_t uid = getUid(); | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 446 | pid_t pid = getPid(); | 
|  | 447 | std::string name = android::base::StringPrintf("%5u/%u", pid, uid); | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 448 | std::string size = android::base::StringPrintf("%zu", getSizes()); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 449 |  | 
| Mark Salyzyn | f31ae3d | 2017-04-13 15:35:22 -0700 | [diff] [blame] | 450 | formatTmp(stat, getName(), uid, name, size, 12); | 
|  | 451 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 452 | std::string pruned = ""; | 
|  | 453 | size_t dropped = getDropped(); | 
|  | 454 | if (dropped) { | 
|  | 455 | pruned = android::base::StringPrintf("%zu", dropped); | 
|  | 456 | } | 
|  | 457 |  | 
|  | 458 | return formatLine(name, size, pruned); | 
|  | 459 | } | 
|  | 460 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 461 | std::string TidEntry::formatHeader(const std::string& name, | 
|  | 462 | log_id_t /* id */) const { | 
|  | 463 | return formatLine(name, std::string("Size"), std::string("Pruned")) + | 
|  | 464 | formatLine(std::string("  TID/UID   COMM"), std::string("BYTES"), | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 465 | std::string("NUM")); | 
|  | 466 | } | 
|  | 467 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 468 | std::string TidEntry::format(const LogStatistics& stat, | 
|  | 469 | log_id_t /* id */) const { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 470 | uid_t uid = getUid(); | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 471 | std::string name = android::base::StringPrintf("%5u/%u", getTid(), uid); | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 472 | std::string size = android::base::StringPrintf("%zu", getSizes()); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 473 |  | 
| Mark Salyzyn | f31ae3d | 2017-04-13 15:35:22 -0700 | [diff] [blame] | 474 | formatTmp(stat, getName(), uid, name, size, 12); | 
|  | 475 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 476 | std::string pruned = ""; | 
|  | 477 | size_t dropped = getDropped(); | 
|  | 478 | if (dropped) { | 
|  | 479 | pruned = android::base::StringPrintf("%zu", dropped); | 
|  | 480 | } | 
|  | 481 |  | 
|  | 482 | return formatLine(name, size, pruned); | 
|  | 483 | } | 
|  | 484 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 485 | std::string TagEntry::formatHeader(const std::string& name, log_id_t id) const { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 486 | bool isprune = worstUidEnabledForLogid(id); | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 487 | return formatLine(name, std::string("Size"), | 
|  | 488 | std::string(isprune ? "Prune" : "")) + | 
|  | 489 | formatLine(std::string("    TAG/UID   TAGNAME"), | 
|  | 490 | std::string("BYTES"), std::string(isprune ? "NUM" : "")); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 491 | } | 
|  | 492 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 493 | std::string TagEntry::format(const LogStatistics& /* stat */, | 
|  | 494 | log_id_t /* id */) const { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 495 | std::string name; | 
|  | 496 | uid_t uid = getUid(); | 
|  | 497 | if (uid == (uid_t)-1) { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 498 | name = android::base::StringPrintf("%7u", getKey()); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 499 | } else { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 500 | name = android::base::StringPrintf("%7u/%u", getKey(), uid); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 501 | } | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 502 | const char* nameTmp = getName(); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 503 | if (nameTmp) { | 
|  | 504 | name += android::base::StringPrintf( | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 505 | "%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", nameTmp); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 506 | } | 
|  | 507 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 508 | std::string size = android::base::StringPrintf("%zu", getSizes()); | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 509 |  | 
|  | 510 | std::string pruned = ""; | 
| Mark Salyzyn | 6a06694 | 2016-07-14 15:34:30 -0700 | [diff] [blame] | 511 | size_t dropped = getDropped(); | 
|  | 512 | if (dropped) { | 
|  | 513 | pruned = android::base::StringPrintf("%zu", dropped); | 
|  | 514 | } | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 515 |  | 
|  | 516 | return formatLine(name, size, pruned); | 
|  | 517 | } | 
|  | 518 |  | 
| Mark Salyzyn | f99a7d6 | 2017-04-19 14:39:21 -0700 | [diff] [blame] | 519 | std::string TagNameEntry::formatHeader(const std::string& name, | 
|  | 520 | log_id_t /* id */) const { | 
|  | 521 | return formatLine(name, std::string("Size"), std::string("")) + | 
|  | 522 | formatLine(std::string("  TID/PID/UID   LOG_TAG NAME"), | 
|  | 523 | std::string("BYTES"), std::string("")); | 
|  | 524 | } | 
|  | 525 |  | 
|  | 526 | std::string TagNameEntry::format(const LogStatistics& /* stat */, | 
|  | 527 | log_id_t /* id */) const { | 
|  | 528 | std::string name; | 
|  | 529 | pid_t tid = getTid(); | 
|  | 530 | pid_t pid = getPid(); | 
|  | 531 | std::string pidstr; | 
|  | 532 | if (pid != (pid_t)-1) { | 
|  | 533 | pidstr = android::base::StringPrintf("%u", pid); | 
|  | 534 | if ((tid != (pid_t)-1) && (tid != pid)) pidstr = "/" + pidstr; | 
|  | 535 | } | 
|  | 536 | int len = 9 - pidstr.length(); | 
|  | 537 | if (len < 0) len = 0; | 
|  | 538 | if ((tid == (pid_t)-1) || (tid == pid)) { | 
|  | 539 | name = android::base::StringPrintf("%*s", len, ""); | 
|  | 540 | } else { | 
|  | 541 | name = android::base::StringPrintf("%*u", len, tid); | 
|  | 542 | } | 
|  | 543 | name += pidstr; | 
|  | 544 | uid_t uid = getUid(); | 
|  | 545 | if (uid != (uid_t)-1) { | 
|  | 546 | name += android::base::StringPrintf("/%u", uid); | 
|  | 547 | } | 
|  | 548 |  | 
|  | 549 | std::string size = android::base::StringPrintf("%zu", getSizes()); | 
|  | 550 |  | 
|  | 551 | const char* nameTmp = getName(); | 
|  | 552 | if (nameTmp) { | 
|  | 553 | size_t lenSpace = std::max(16 - name.length(), (size_t)1); | 
|  | 554 | size_t len = EntryBaseConstants::total_len - | 
|  | 555 | EntryBaseConstants::pruned_len - size.length() - | 
|  | 556 | name.length() - lenSpace - 2; | 
|  | 557 | size_t lenNameTmp = strlen(nameTmp); | 
|  | 558 | while ((len < lenNameTmp) && (lenSpace > 1)) { | 
|  | 559 | ++len; | 
|  | 560 | --lenSpace; | 
|  | 561 | } | 
|  | 562 | name += android::base::StringPrintf("%*s", (int)lenSpace, ""); | 
|  | 563 | if (len < lenNameTmp) { | 
|  | 564 | name += "..."; | 
|  | 565 | nameTmp += lenNameTmp - std::max(len - 3, (size_t)1); | 
|  | 566 | } | 
|  | 567 | name += nameTmp; | 
|  | 568 | } | 
|  | 569 |  | 
|  | 570 | std::string pruned = ""; | 
|  | 571 |  | 
|  | 572 | return formatLine(name, size, pruned); | 
|  | 573 | } | 
|  | 574 |  | 
| Mark Salyzyn | 03bb759 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 575 | static std::string formatMsec(uint64_t val) { | 
|  | 576 | static const unsigned subsecDigits = 3; | 
|  | 577 | static const uint64_t sec = MS_PER_SEC; | 
|  | 578 |  | 
|  | 579 | static const uint64_t minute = 60 * sec; | 
|  | 580 | static const uint64_t hour = 60 * minute; | 
|  | 581 | static const uint64_t day = 24 * hour; | 
|  | 582 |  | 
|  | 583 | std::string output; | 
|  | 584 | if (val < sec) return output; | 
|  | 585 |  | 
|  | 586 | if (val >= day) { | 
|  | 587 | output = android::base::StringPrintf("%" PRIu64 "d ", val / day); | 
|  | 588 | val = (val % day) + day; | 
|  | 589 | } | 
|  | 590 | if (val >= minute) { | 
|  | 591 | if (val >= hour) { | 
|  | 592 | output += android::base::StringPrintf("%" PRIu64 ":", | 
|  | 593 | (val / hour) % (day / hour)); | 
|  | 594 | } | 
|  | 595 | output += android::base::StringPrintf( | 
|  | 596 | (val >= hour) ? "%02" PRIu64 ":" : "%" PRIu64 ":", | 
|  | 597 | (val / minute) % (hour / minute)); | 
|  | 598 | } | 
|  | 599 | output += | 
|  | 600 | android::base::StringPrintf((val >= minute) ? "%02" PRIu64 : "%" PRIu64, | 
|  | 601 | (val / sec) % (minute / sec)); | 
|  | 602 | val %= sec; | 
|  | 603 | unsigned digits = subsecDigits; | 
|  | 604 | while (digits && ((val % 10) == 0)) { | 
|  | 605 | val /= 10; | 
|  | 606 | --digits; | 
|  | 607 | } | 
|  | 608 | if (digits) { | 
|  | 609 | output += android::base::StringPrintf(".%0*" PRIu64, digits, val); | 
|  | 610 | } | 
|  | 611 | return output; | 
|  | 612 | } | 
|  | 613 |  | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 614 | std::string LogStatistics::format(uid_t uid, pid_t pid, | 
|  | 615 | unsigned int logMask) const { | 
| Chih-Hung Hsieh | 08d470b | 2018-08-13 14:22:56 -0700 | [diff] [blame] | 616 | static const uint16_t spaces_total = 19; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 617 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 618 | // Report on total logging, current and for all time | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 619 |  | 
| Mark Salyzyn | decbcd9 | 2015-08-19 15:33:01 -0700 | [diff] [blame] | 620 | std::string output = "size/num"; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 621 | size_t oldLength; | 
| Chih-Hung Hsieh | 08d470b | 2018-08-13 14:22:56 -0700 | [diff] [blame] | 622 | int16_t spaces = 1; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 623 |  | 
|  | 624 | log_id_for_each(id) { | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 625 | if (!(logMask & (1 << id))) continue; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 626 | oldLength = output.length(); | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 627 | if (spaces < 0) spaces = 0; | 
| Mark Salyzyn | decbcd9 | 2015-08-19 15:33:01 -0700 | [diff] [blame] | 628 | output += android::base::StringPrintf("%*s%s", spaces, "", | 
|  | 629 | android_log_id_to_name(id)); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 630 | spaces += spaces_total + oldLength - output.length(); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 631 | } | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 632 | if (spaces < 0) spaces = 0; | 
|  | 633 | output += android::base::StringPrintf("%*sTotal", spaces, ""); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 634 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 635 | static const char TotalStr[] = "\nTotal"; | 
|  | 636 | spaces = 10 - strlen(TotalStr); | 
|  | 637 | output += TotalStr; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 638 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 639 | size_t totalSize = 0; | 
|  | 640 | size_t totalEls = 0; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 641 | log_id_for_each(id) { | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 642 | if (!(logMask & (1 << id))) continue; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 643 | oldLength = output.length(); | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 644 | if (spaces < 0) spaces = 0; | 
|  | 645 | size_t szs = sizesTotal(id); | 
|  | 646 | totalSize += szs; | 
|  | 647 | size_t els = elementsTotal(id); | 
|  | 648 | totalEls += els; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 649 | output += | 
|  | 650 | android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 651 | spaces += spaces_total + oldLength - output.length(); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 652 | } | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 653 | if (spaces < 0) spaces = 0; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 654 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, | 
|  | 655 | totalEls); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 656 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 657 | static const char NowStr[] = "\nNow"; | 
|  | 658 | spaces = 10 - strlen(NowStr); | 
|  | 659 | output += NowStr; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 660 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 661 | totalSize = 0; | 
|  | 662 | totalEls = 0; | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 663 | log_id_for_each(id) { | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 664 | if (!(logMask & (1 << id))) continue; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 665 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 666 | size_t els = elements(id); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 667 | if (els) { | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 668 | oldLength = output.length(); | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 669 | if (spaces < 0) spaces = 0; | 
|  | 670 | size_t szs = sizes(id); | 
|  | 671 | totalSize += szs; | 
|  | 672 | totalEls += els; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 673 | output += | 
|  | 674 | android::base::StringPrintf("%*s%zu/%zu", spaces, "", szs, els); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 675 | spaces -= output.length() - oldLength; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 676 | } | 
|  | 677 | spaces += spaces_total; | 
|  | 678 | } | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 679 | if (spaces < 0) spaces = 0; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 680 | output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize, | 
|  | 681 | totalEls); | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 682 |  | 
| Mark Salyzyn | 03bb759 | 2017-04-14 09:46:57 -0700 | [diff] [blame] | 683 | static const char SpanStr[] = "\nLogspan"; | 
|  | 684 | spaces = 10 - strlen(SpanStr); | 
|  | 685 | output += SpanStr; | 
|  | 686 |  | 
|  | 687 | // Total reports the greater of the individual maximum time span, or the | 
|  | 688 | // validated minimum start and maximum end time span if it makes sense. | 
|  | 689 | uint64_t minTime = UINT64_MAX; | 
|  | 690 | uint64_t maxTime = 0; | 
|  | 691 | uint64_t maxSpan = 0; | 
|  | 692 | totalSize = 0; | 
|  | 693 |  | 
|  | 694 | log_id_for_each(id) { | 
|  | 695 | if (!(logMask & (1 << id))) continue; | 
|  | 696 |  | 
|  | 697 | // validity checking | 
|  | 698 | uint64_t oldest = mOldest[id].msec(); | 
|  | 699 | uint64_t newest = mNewest[id].msec(); | 
|  | 700 | if (newest <= oldest) { | 
|  | 701 | spaces += spaces_total; | 
|  | 702 | continue; | 
|  | 703 | } | 
|  | 704 |  | 
|  | 705 | uint64_t span = newest - oldest; | 
|  | 706 | if (span > (monthSec * MS_PER_SEC)) { | 
|  | 707 | spaces += spaces_total; | 
|  | 708 | continue; | 
|  | 709 | } | 
|  | 710 |  | 
|  | 711 | // total span | 
|  | 712 | if (minTime > oldest) minTime = oldest; | 
|  | 713 | if (maxTime < newest) maxTime = newest; | 
|  | 714 | if (span > maxSpan) maxSpan = span; | 
|  | 715 | totalSize += span; | 
|  | 716 |  | 
|  | 717 | uint64_t dropped = mNewestDropped[id].msec(); | 
|  | 718 | if (dropped < oldest) dropped = oldest; | 
|  | 719 | if (dropped > newest) dropped = newest; | 
|  | 720 |  | 
|  | 721 | oldLength = output.length(); | 
|  | 722 | output += android::base::StringPrintf("%*s%s", spaces, "", | 
|  | 723 | formatMsec(span).c_str()); | 
|  | 724 | unsigned permille = ((newest - dropped) * 1000 + (span / 2)) / span; | 
|  | 725 | if ((permille > 1) && (permille < 999)) { | 
|  | 726 | output += android::base::StringPrintf("(%u", permille / 10); | 
|  | 727 | permille %= 10; | 
|  | 728 | if (permille) { | 
|  | 729 | output += android::base::StringPrintf(".%u", permille); | 
|  | 730 | } | 
|  | 731 | output += android::base::StringPrintf("%%)"); | 
|  | 732 | } | 
|  | 733 | spaces -= output.length() - oldLength; | 
|  | 734 | spaces += spaces_total; | 
|  | 735 | } | 
|  | 736 | if ((maxTime > minTime) && ((maxTime -= minTime) < totalSize) && | 
|  | 737 | (maxTime > maxSpan)) { | 
|  | 738 | maxSpan = maxTime; | 
|  | 739 | } | 
|  | 740 | if (spaces < 0) spaces = 0; | 
|  | 741 | output += android::base::StringPrintf("%*s%s", spaces, "", | 
|  | 742 | formatMsec(maxSpan).c_str()); | 
|  | 743 |  | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 744 | static const char OverheadStr[] = "\nOverhead"; | 
|  | 745 | spaces = 10 - strlen(OverheadStr); | 
|  | 746 | output += OverheadStr; | 
|  | 747 |  | 
|  | 748 | totalSize = 0; | 
|  | 749 | log_id_for_each(id) { | 
|  | 750 | if (!(logMask & (1 << id))) continue; | 
|  | 751 |  | 
|  | 752 | size_t els = elements(id); | 
|  | 753 | if (els) { | 
|  | 754 | oldLength = output.length(); | 
|  | 755 | if (spaces < 0) spaces = 0; | 
|  | 756 | // estimate the std::list overhead. | 
|  | 757 | static const size_t overhead = | 
|  | 758 | ((sizeof(LogBufferElement) + sizeof(uint64_t) - 1) & | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 759 | -sizeof(uint64_t)) + | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 760 | sizeof(std::list<LogBufferElement*>); | 
|  | 761 | size_t szs = sizes(id) + els * overhead; | 
|  | 762 | totalSize += szs; | 
|  | 763 | output += android::base::StringPrintf("%*s%zu", spaces, "", szs); | 
|  | 764 | spaces -= output.length() - oldLength; | 
|  | 765 | } | 
|  | 766 | spaces += spaces_total; | 
|  | 767 | } | 
| Mark Salyzyn | 6d981af | 2016-10-06 09:55:21 -0700 | [diff] [blame] | 768 | totalSize += sizeOf(); | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 769 | if (spaces < 0) spaces = 0; | 
|  | 770 | output += android::base::StringPrintf("%*s%zu", spaces, "", totalSize); | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 771 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 772 | // Report on Chattiest | 
| Mark Salyzyn | 8e72c53 | 2014-03-26 10:46:39 -0700 | [diff] [blame] | 773 |  | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 774 | std::string name; | 
|  | 775 |  | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 776 | // Chattiest by application (UID) | 
|  | 777 | log_id_for_each(id) { | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 778 | if (!(logMask & (1 << id))) continue; | 
| Mark Salyzyn | 8e72c53 | 2014-03-26 10:46:39 -0700 | [diff] [blame] | 779 |  | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 780 | name = (uid == AID_ROOT) ? "Chattiest UIDs in %s log buffer:" | 
|  | 781 | : "Logging for your UID in %s log buffer:"; | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 782 | output += uidTable[id].format(*this, uid, pid, name, id); | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 783 | } | 
| Mark Salyzyn | 8e72c53 | 2014-03-26 10:46:39 -0700 | [diff] [blame] | 784 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 785 | if (enable) { | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 786 | name = ((uid == AID_ROOT) && !pid) ? "Chattiest PIDs:" | 
|  | 787 | : "Logging for this PID:"; | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 788 | output += pidTable.format(*this, uid, pid, name); | 
|  | 789 | name = "Chattiest TIDs"; | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 790 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 791 | name += ":"; | 
|  | 792 | output += tidTable.format(*this, uid, pid, name); | 
| Mark Salyzyn | 17ed679 | 2015-04-20 13:35:15 -0700 | [diff] [blame] | 793 | } | 
|  | 794 |  | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 795 | if (enable && (logMask & (1 << LOG_ID_EVENTS))) { | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 796 | name = "Chattiest events log buffer TAGs"; | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 797 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 798 | name += ":"; | 
|  | 799 | output += tagTable.format(*this, uid, pid, name, LOG_ID_EVENTS); | 
| Mark Salyzyn | 344bff4 | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 800 | } | 
|  | 801 |  | 
| Mark Salyzyn | 083b037 | 2015-12-04 10:59:45 -0800 | [diff] [blame] | 802 | if (enable && (logMask & (1 << LOG_ID_SECURITY))) { | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 803 | name = "Chattiest security log buffer TAGs"; | 
| Mark Salyzyn | 9af33ee | 2016-10-05 12:34:37 -0700 | [diff] [blame] | 804 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); | 
| Mark Salyzyn | ee3b838 | 2015-12-17 09:58:43 -0800 | [diff] [blame] | 805 | name += ":"; | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 806 | output += | 
|  | 807 | securityTagTable.format(*this, uid, pid, name, LOG_ID_SECURITY); | 
| Mark Salyzyn | 083b037 | 2015-12-04 10:59:45 -0800 | [diff] [blame] | 808 | } | 
|  | 809 |  | 
| Mark Salyzyn | f99a7d6 | 2017-04-19 14:39:21 -0700 | [diff] [blame] | 810 | if (enable) { | 
|  | 811 | name = "Chattiest TAGs"; | 
|  | 812 | if (pid) name += android::base::StringPrintf(" for PID %d", pid); | 
|  | 813 | name += ":"; | 
|  | 814 | output += tagNameTable.format(*this, uid, pid, name); | 
|  | 815 | } | 
|  | 816 |  | 
| Mark Salyzyn | 73160ac | 2015-08-20 10:01:44 -0700 | [diff] [blame] | 817 | return output; | 
| Mark Salyzyn | 34facab | 2014-02-06 14:48:50 -0800 | [diff] [blame] | 818 | } | 
| Mark Salyzyn | 4ba0387 | 2014-04-07 07:15:33 -0700 | [diff] [blame] | 819 |  | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 820 | namespace android { | 
|  | 821 |  | 
|  | 822 | uid_t pidToUid(pid_t pid) { | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 823 | char buffer[512]; | 
|  | 824 | snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid); | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 825 | FILE* fp = fopen(buffer, "r"); | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 826 | if (fp) { | 
|  | 827 | while (fgets(buffer, sizeof(buffer), fp)) { | 
| Mark Salyzyn | c4e4823 | 2017-05-04 13:54:46 -0700 | [diff] [blame] | 828 | int uid = AID_LOGD; | 
|  | 829 | char space = 0; | 
|  | 830 | if ((sscanf(buffer, "Uid: %d%c", &uid, &space) == 2) && | 
|  | 831 | isspace(space)) { | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 832 | fclose(fp); | 
|  | 833 | return uid; | 
| Mark Salyzyn | 4ba0387 | 2014-04-07 07:15:33 -0700 | [diff] [blame] | 834 | } | 
|  | 835 | } | 
| Mark Salyzyn | 97c1c2b | 2015-03-10 13:51:35 -0700 | [diff] [blame] | 836 | fclose(fp); | 
| Mark Salyzyn | 4ba0387 | 2014-04-07 07:15:33 -0700 | [diff] [blame] | 837 | } | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 838 | return AID_LOGD;  // associate this with the logger | 
| Mark Salyzyn | 4ba0387 | 2014-04-07 07:15:33 -0700 | [diff] [blame] | 839 | } | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 840 | } | 
|  | 841 |  | 
|  | 842 | uid_t LogStatistics::pidToUid(pid_t pid) { | 
| Mark Salyzyn | 511338d | 2015-05-19 09:12:30 -0700 | [diff] [blame] | 843 | return pidTable.add(pid)->second.getUid(); | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 844 | } | 
|  | 845 |  | 
|  | 846 | // caller must free character string | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 847 | const char* LogStatistics::pidToName(pid_t pid) const { | 
| Mark Salyzyn | 758058f | 2015-08-21 16:44:30 -0700 | [diff] [blame] | 848 | // An inconvenient truth ... getName() can alter the object | 
| Mark Salyzyn | 501c373 | 2017-03-10 14:31:54 -0800 | [diff] [blame] | 849 | pidTable_t& writablePidTable = const_cast<pidTable_t&>(pidTable); | 
|  | 850 | const char* name = writablePidTable.add(pid)->second.getName(); | 
| Mark Salyzyn | 81b3eab | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 851 | if (!name) { | 
| Yi Kong | c8d09dd | 2018-07-13 17:39:22 -0700 | [diff] [blame] | 852 | return nullptr; | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 853 | } | 
| Mark Salyzyn | 81b3eab | 2015-04-13 14:24:45 -0700 | [diff] [blame] | 854 | return strdup(name); | 
| Mark Salyzyn | 720f6d1 | 2015-03-16 08:26:05 -0700 | [diff] [blame] | 855 | } |