blob: 8fc4e56343828caba4fe147d397462c8fcfa8281 [file] [log] [blame]
Mark Salyzyn34facab2014-02-06 14:48:50 -08001/*
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 Salyzyn97c1c2b2015-03-10 13:51:35 -070017#include <algorithm> // std::max
Mark Salyzyn9a038632014-04-07 07:05:40 -070018#include <fcntl.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070019#include <stdio.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070020#include <string.h>
21#include <unistd.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080022
23#include <log/logger.h>
24#include <private/android_filesystem_config.h>
25#include <utils/String8.h>
26
27#include "LogStatistics.h"
28
Mark Salyzyn720f6d12015-03-16 08:26:05 -070029LogStatistics::LogStatistics()
30 : enable(false) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070031 log_id_for_each(id) {
32 mSizes[id] = 0;
33 mElements[id] = 0;
34 mSizesTotal[id] = 0;
35 mElementsTotal[id] = 0;
Mark Salyzyn34facab2014-02-06 14:48:50 -080036 }
37}
38
Mark Salyzyn720f6d12015-03-16 08:26:05 -070039namespace android {
40
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070041// caller must own and free character string
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070042char *pidToName(pid_t pid) {
Mark Salyzyn9a038632014-04-07 07:05:40 -070043 char *retval = NULL;
Mark Salyzyndf5aa612014-09-21 14:22:18 -070044 if (pid == 0) { // special case from auditd for kernel
45 retval = strdup("logd.auditd");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070046 } else {
Mark Salyzyn9a038632014-04-07 07:05:40 -070047 char buffer[512];
48 snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
49 int fd = open(buffer, O_RDONLY);
50 if (fd >= 0) {
51 ssize_t ret = read(fd, buffer, sizeof(buffer));
52 if (ret > 0) {
53 buffer[sizeof(buffer)-1] = '\0';
54 // frameworks intermediate state
55 if (strcmp(buffer, "<pre-initialized>")) {
56 retval = strdup(buffer);
57 }
58 }
59 close(fd);
60 }
61 }
62 return retval;
63}
64
Mark Salyzyn720f6d12015-03-16 08:26:05 -070065}
66
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070067void LogStatistics::add(LogBufferElement *e) {
68 log_id_t log_id = e->getLogId();
69 unsigned short size = e->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080070 mSizes[log_id] += size;
71 ++mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070072
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070073 uidTable[log_id].add(e->getUid(), e);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070074
75 mSizesTotal[log_id] += size;
76 ++mElementsTotal[log_id];
Mark Salyzyn720f6d12015-03-16 08:26:05 -070077
78 if (!enable) {
79 return;
80 }
81
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070082 pidTable.add(e->getPid(), e);
Mark Salyzyn17ed6792015-04-20 13:35:15 -070083 tidTable.add(e->getTid(), e);
Mark Salyzyn344bff42015-04-13 14:24:45 -070084
85 uint32_t tag = e->getTag();
86 if (tag) {
87 tagTable.add(tag, e);
88 }
Mark Salyzyn34facab2014-02-06 14:48:50 -080089}
90
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070091void LogStatistics::subtract(LogBufferElement *e) {
92 log_id_t log_id = e->getLogId();
93 unsigned short size = e->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080094 mSizes[log_id] -= size;
95 --mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070096
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070097 uidTable[log_id].subtract(e->getUid(), e);
Mark Salyzyn34facab2014-02-06 14:48:50 -080098
Mark Salyzyn720f6d12015-03-16 08:26:05 -070099 if (!enable) {
100 return;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800101 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700102
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700103 pidTable.subtract(e->getPid(), e);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700104 tidTable.subtract(e->getTid(), e);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700105
106 uint32_t tag = e->getTag();
107 if (tag) {
108 tagTable.subtract(tag, e);
109 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800110}
111
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700112// Atomically set an entry to drop
113// entry->setDropped(1) must follow this call, caller should do this explicitly.
114void LogStatistics::drop(LogBufferElement *e) {
115 log_id_t log_id = e->getLogId();
116 unsigned short size = e->getMsgLen();
117 mSizes[log_id] -= size;
118
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700119 uidTable[log_id].drop(e->getUid(), e);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700120
121 if (!enable) {
122 return;
123 }
124
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700125 pidTable.drop(e->getPid(), e);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700126 tidTable.drop(e->getTid(), e);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700127}
128
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700129// caller must own and free character string
130char *LogStatistics::uidToName(uid_t uid) {
131 // Local hard coded favourites
132 if (uid == AID_LOGD) {
133 return strdup("auditd");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800134 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700135
136 // Android hard coded
137 const struct android_id_info *info = android_ids;
138
139 for (size_t i = 0; i < android_id_count; ++i) {
140 if (info->aid == uid) {
141 return strdup(info->name);
142 }
143 ++info;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800144 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700145
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700146 // Parse /data/system/packages.list
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700147 uid_t userId = uid % AID_USER;
148 char *name = android::uidToName(userId);
149 if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
150 name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
151 }
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700152 if (name) {
153 return name;
154 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700155
156 // report uid -> pid(s) -> pidToName if unique
157 ssize_t index = -1;
158 while ((index = pidTable.next(index)) != -1) {
159 const PidEntry &entry = pidTable.entryAt(index);
160
161 if (entry.getUid() == uid) {
162 const char *n = entry.getName();
163
164 if (n) {
165 if (!name) {
166 name = strdup(n);
167 } else if (strcmp(name, n)) {
168 free(name);
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700169 name = NULL;
170 break;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700171 }
172 }
173 }
174 }
175
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700176 // No one
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700177 return name;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800178}
179
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700180static void format_line(android::String8 &output,
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700181 android::String8 &name, android::String8 &size, android::String8 &pruned) {
182 static const size_t pruned_len = 6;
183 static const size_t total_len = 70 + pruned_len;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700184
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700185 ssize_t drop_len = std::max(pruned.length() + 1, pruned_len);
186 ssize_t size_len = std::max(size.length() + 1,
187 total_len - name.length() - drop_len - 1);
188
189 if (pruned.length()) {
190 output.appendFormat("%s%*s%*s\n", name.string(),
191 (int)size_len, size.string(),
192 (int)drop_len, pruned.string());
193 } else {
194 output.appendFormat("%s%*s\n", name.string(),
195 (int)size_len, size.string());
196 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800197}
198
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700199void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
Mark Salyzyn9a038632014-04-07 07:05:40 -0700200 static const unsigned short spaces_total = 19;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800201
202 if (*buf) {
Greg Hackmann239605e2014-04-06 21:25:58 -0700203 free(*buf);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800204 *buf = NULL;
205 }
206
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700207 // Report on total logging, current and for all time
Mark Salyzyn34facab2014-02-06 14:48:50 -0800208
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700209 android::String8 output("size/num");
210 size_t oldLength;
211 short spaces = 1;
212
213 log_id_for_each(id) {
214 if (!(logMask & (1 << id))) {
Mark Salyzync8a576c2014-04-04 16:35:59 -0700215 continue;
216 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700217 oldLength = output.length();
Mark Salyzync8a576c2014-04-04 16:35:59 -0700218 if (spaces < 0) {
219 spaces = 0;
220 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700221 output.appendFormat("%*s%s", spaces, "", android_log_id_to_name(id));
222 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800223 }
224
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700225 spaces = 4;
226 output.appendFormat("\nTotal");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800227
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700228 log_id_for_each(id) {
229 if (!(logMask & (1 << id))) {
230 continue;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800231 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700232 oldLength = output.length();
233 if (spaces < 0) {
234 spaces = 0;
235 }
236 output.appendFormat("%*s%zu/%zu", spaces, "",
237 sizesTotal(id), elementsTotal(id));
238 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800239 }
240
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700241 spaces = 6;
242 output.appendFormat("\nNow");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800243
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700244 log_id_for_each(id) {
245 if (!(logMask & (1 << id))) {
Mark Salyzyn34facab2014-02-06 14:48:50 -0800246 continue;
247 }
248
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700249 size_t els = elements(id);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800250 if (els) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700251 oldLength = output.length();
Mark Salyzyne457b742014-02-19 17:18:31 -0800252 if (spaces < 0) {
253 spaces = 0;
254 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700255 output.appendFormat("%*s%zu/%zu", spaces, "", sizes(id), els);
256 spaces -= output.length() - oldLength;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800257 }
258 spaces += spaces_total;
259 }
260
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700261 // Report on Chattiest
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700262
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700263 // Chattiest by application (UID)
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700264 static const size_t maximum_sorted_entries = 32;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700265 log_id_for_each(id) {
266 if (!(logMask & (1 << id))) {
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700267 continue;
268 }
269
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700270 bool headerPrinted = false;
271 std::unique_ptr<const UidEntry *[]> sorted = sort(maximum_sorted_entries, id);
272 ssize_t index = -1;
273 while ((index = uidTable_t::next(index, sorted, maximum_sorted_entries)) >= 0) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700274 const UidEntry *entry = sorted[index];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700275 uid_t u = entry->getKey();
276 if ((uid != AID_ROOT) && (u != uid)) {
277 continue;
278 }
279
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700280 if (!headerPrinted) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700281 output.appendFormat("\n\n");
282 android::String8 name("");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700283 if (uid == AID_ROOT) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700284 name.appendFormat(
285 "Chattiest UIDs in %s log buffer:",
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700286 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700287 } else {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700288 name.appendFormat(
289 "Logging for your UID in %s log buffer:",
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700290 android_log_id_to_name(id));
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700291 }
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700292 android::String8 size("Size");
293 android::String8 pruned("Pruned");
Mark Salyzynae769232015-03-17 17:17:25 -0700294 if (!worstUidEnabledForLogid(id)) {
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700295 pruned.setTo("");
296 }
297 format_line(output, name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700298
299 name.setTo("UID PACKAGE");
300 size.setTo("BYTES");
301 pruned.setTo("LINES");
302 if (!worstUidEnabledForLogid(id)) {
303 pruned.setTo("");
304 }
305 format_line(output, name, size, pruned);
306
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700307 headerPrinted = true;
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700308 }
309
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700310 android::String8 name("");
311 name.appendFormat("%u", u);
312 char *n = uidToName(u);
313 if (n) {
314 name.appendFormat("%*s%s", (int)std::max(6 - name.length(), (size_t)1), "", n);
315 free(n);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700316 }
317
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700318 android::String8 size("");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700319 size.appendFormat("%zu", entry->getSizes());
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700320
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700321 android::String8 pruned("");
322 size_t dropped = entry->getDropped();
323 if (dropped) {
324 pruned.appendFormat("%zu", dropped);
325 }
326
327 format_line(output, name, size, pruned);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700328 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700329 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700330
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700331 if (enable) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700332 // Pid table
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700333 bool headerPrinted = false;
334 std::unique_ptr<const PidEntry *[]> sorted = pidTable.sort(maximum_sorted_entries);
335 ssize_t index = -1;
336 while ((index = pidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
337 const PidEntry *entry = sorted[index];
338 uid_t u = entry->getUid();
339 if ((uid != AID_ROOT) && (u != uid)) {
340 continue;
341 }
342
343 if (!headerPrinted) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700344 output.appendFormat("\n\n");
345 android::String8 name("");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700346 if (uid == AID_ROOT) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700347 name.appendFormat("Chattiest PIDs:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700348 } else {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700349 name.appendFormat("Logging for this PID:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700350 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700351 android::String8 size("Size");
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700352 android::String8 pruned("Pruned");
353 format_line(output, name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700354
355 name.setTo(" PID/UID COMMAND LINE");
356 size.setTo("BYTES");
357 pruned.setTo("LINES");
358 format_line(output, name, size, pruned);
359
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700360 headerPrinted = true;
361 }
362
363 android::String8 name("");
364 name.appendFormat("%5u/%u", entry->getKey(), u);
365 const char *n = entry->getName();
366 if (n) {
367 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", n);
368 } else {
369 char *un = uidToName(u);
370 if (un) {
371 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", un);
372 free(un);
373 }
374 }
375
376 android::String8 size("");
377 size.appendFormat("%zu", entry->getSizes());
378
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700379 android::String8 pruned("");
380 size_t dropped = entry->getDropped();
381 if (dropped) {
382 pruned.appendFormat("%zu", dropped);
383 }
384
385 format_line(output, name, size, pruned);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700386 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700387 }
388
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700389 if (enable) {
390 // Tid table
391 bool headerPrinted = false;
392 // sort() returns list of references, unique_ptr makes sure self-delete
393 std::unique_ptr<const TidEntry *[]> sorted = tidTable.sort(maximum_sorted_entries);
394 ssize_t index = -1;
395 while ((index = tidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
396 const TidEntry *entry = sorted[index];
397 uid_t u = entry->getUid();
398 if ((uid != AID_ROOT) && (u != uid)) {
399 continue;
400 }
401
402 if (!headerPrinted) { // Only print header if we have table to print
403 output.appendFormat("\n\n");
404 android::String8 name("Chattiest TIDs:");
405 android::String8 size("Size");
406 android::String8 pruned("Pruned");
407 format_line(output, name, size, pruned);
408
409 name.setTo(" TID/UID COMM");
410 size.setTo("BYTES");
411 pruned.setTo("LINES");
412 format_line(output, name, size, pruned);
413
414 headerPrinted = true;
415 }
416
417 android::String8 name("");
418 name.appendFormat("%5u/%u", entry->getKey(), u);
419 const char *n = entry->getName();
420 if (n) {
421 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", n);
422 } else {
423 // if we do not have a PID name, lets punt to try UID name?
424 char *un = uidToName(u);
425 if (un) {
426 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", un);
427 free(un);
428 }
429 // We tried, better to not have a name at all, we still
430 // have TID/UID by number to report in any case.
431 }
432
433 android::String8 size("");
434 size.appendFormat("%zu", entry->getSizes());
435
436 android::String8 pruned("");
437 size_t dropped = entry->getDropped();
438 if (dropped) {
439 pruned.appendFormat("%zu", dropped);
440 }
441
442 format_line(output, name, size, pruned);
443 }
444 }
445
Mark Salyzyn344bff42015-04-13 14:24:45 -0700446 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
447 // Tag table
448 bool headerPrinted = false;
449 std::unique_ptr<const TagEntry *[]> sorted = tagTable.sort(maximum_sorted_entries);
450 ssize_t index = -1;
451 while ((index = tagTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
452 const TagEntry *entry = sorted[index];
453 uid_t u = entry->getUid();
454 if ((uid != AID_ROOT) && (u != uid)) {
455 continue;
456 }
457
458 android::String8 pruned("");
459
460 if (!headerPrinted) {
461 output.appendFormat("\n\n");
462 android::String8 name("Chattiest events log buffer TAGs:");
463 android::String8 size("Size");
464 format_line(output, name, size, pruned);
465
466 name.setTo(" TAG/UID TAGNAME");
467 size.setTo("BYTES");
468 format_line(output, name, size, pruned);
469
470 headerPrinted = true;
471 }
472
473 android::String8 name("");
474 if (u == (uid_t)-1) {
475 name.appendFormat("%7u", entry->getKey());
476 } else {
477 name.appendFormat("%7u/%u", entry->getKey(), u);
478 }
479 const char *n = entry->getName();
480 if (n) {
481 name.appendFormat("%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", n);
482 }
483
484 android::String8 size("");
485 size.appendFormat("%zu", entry->getSizes());
486
487 format_line(output, name, size, pruned);
488 }
489 }
490
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700491 *buf = strdup(output.string());
Mark Salyzyn34facab2014-02-06 14:48:50 -0800492}
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700493
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700494namespace android {
495
496uid_t pidToUid(pid_t pid) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700497 char buffer[512];
498 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
499 FILE *fp = fopen(buffer, "r");
500 if (fp) {
501 while (fgets(buffer, sizeof(buffer), fp)) {
502 int uid;
Mark Salyzync32afdf2015-04-14 13:07:29 -0700503 if (sscanf(buffer, "Uid: %d", &uid) == 1) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700504 fclose(fp);
505 return uid;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700506 }
507 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700508 fclose(fp);
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700509 }
Mark Salyzyne3aeeee2015-03-17 07:56:32 -0700510 return AID_LOGD; // associate this with the logger
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700511}
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700512
513}
514
515uid_t LogStatistics::pidToUid(pid_t pid) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700516 return pidTable.entryAt(pidTable.add(pid)).getUid();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700517}
518
519// caller must free character string
520char *LogStatistics::pidToName(pid_t pid) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700521 const char *name = pidTable.entryAt(pidTable.add(pid)).getName();
522 if (!name) {
523 return NULL;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700524 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700525 return strdup(name);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700526}