blob: 9756b2d3eed7aa1316b4fbc20157c44269754bd5 [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 Salyzynae4d9282014-10-15 08:49:39 -070044 if (pid == 0) { // special case from auditd/klogd for kernel
45 retval = strdup("logd");
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 Salyzyn97c1c2b2015-03-10 13:51:35 -070073 mSizesTotal[log_id] += size;
74 ++mElementsTotal[log_id];
Mark Salyzyn720f6d12015-03-16 08:26:05 -070075
Mark Salyzynae4d9282014-10-15 08:49:39 -070076 if (log_id == LOG_ID_KERNEL) {
77 return;
78 }
79
80 uidTable[log_id].add(e->getUid(), e);
81
Mark Salyzyn720f6d12015-03-16 08:26:05 -070082 if (!enable) {
83 return;
84 }
85
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070086 pidTable.add(e->getPid(), e);
Mark Salyzyn344bff42015-04-13 14:24:45 -070087
88 uint32_t tag = e->getTag();
89 if (tag) {
90 tagTable.add(tag, e);
91 }
Mark Salyzyn34facab2014-02-06 14:48:50 -080092}
93
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070094void LogStatistics::subtract(LogBufferElement *e) {
95 log_id_t log_id = e->getLogId();
96 unsigned short size = e->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080097 mSizes[log_id] -= size;
98 --mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070099
Mark Salyzynae4d9282014-10-15 08:49:39 -0700100 if (log_id == LOG_ID_KERNEL) {
101 return;
102 }
103
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700104 uidTable[log_id].subtract(e->getUid(), e);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800105
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700106 if (!enable) {
107 return;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800108 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700109
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700110 pidTable.subtract(e->getPid(), e);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700111
112 uint32_t tag = e->getTag();
113 if (tag) {
114 tagTable.subtract(tag, e);
115 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800116}
117
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700118// Atomically set an entry to drop
119// entry->setDropped(1) must follow this call, caller should do this explicitly.
120void LogStatistics::drop(LogBufferElement *e) {
121 log_id_t log_id = e->getLogId();
122 unsigned short size = e->getMsgLen();
123 mSizes[log_id] -= size;
124
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700125 uidTable[log_id].drop(e->getUid(), e);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700126
127 if (!enable) {
128 return;
129 }
130
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700131 pidTable.drop(e->getPid(), e);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700132}
133
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700134// caller must own and free character string
135char *LogStatistics::uidToName(uid_t uid) {
136 // Local hard coded favourites
137 if (uid == AID_LOGD) {
138 return strdup("auditd");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800139 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700140
141 // Android hard coded
142 const struct android_id_info *info = android_ids;
143
144 for (size_t i = 0; i < android_id_count; ++i) {
145 if (info->aid == uid) {
146 return strdup(info->name);
147 }
148 ++info;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800149 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700150
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700151 // Parse /data/system/packages.list
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700152 uid_t userId = uid % AID_USER;
153 char *name = android::uidToName(userId);
154 if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
155 name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
156 }
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700157 if (name) {
158 return name;
159 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700160
161 // report uid -> pid(s) -> pidToName if unique
162 ssize_t index = -1;
163 while ((index = pidTable.next(index)) != -1) {
164 const PidEntry &entry = pidTable.entryAt(index);
165
166 if (entry.getUid() == uid) {
167 const char *n = entry.getName();
168
169 if (n) {
170 if (!name) {
171 name = strdup(n);
172 } else if (strcmp(name, n)) {
173 free(name);
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700174 name = NULL;
175 break;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700176 }
177 }
178 }
179 }
180
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700181 // No one
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700182 return name;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800183}
184
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700185static void format_line(android::String8 &output,
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700186 android::String8 &name, android::String8 &size, android::String8 &pruned) {
187 static const size_t pruned_len = 6;
188 static const size_t total_len = 70 + pruned_len;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700189
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700190 ssize_t drop_len = std::max(pruned.length() + 1, pruned_len);
191 ssize_t size_len = std::max(size.length() + 1,
192 total_len - name.length() - drop_len - 1);
193
194 if (pruned.length()) {
195 output.appendFormat("%s%*s%*s\n", name.string(),
196 (int)size_len, size.string(),
197 (int)drop_len, pruned.string());
198 } else {
199 output.appendFormat("%s%*s\n", name.string(),
200 (int)size_len, size.string());
201 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800202}
203
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700204void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
Mark Salyzyn9a038632014-04-07 07:05:40 -0700205 static const unsigned short spaces_total = 19;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800206
207 if (*buf) {
Greg Hackmann239605e2014-04-06 21:25:58 -0700208 free(*buf);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800209 *buf = NULL;
210 }
211
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700212 // Report on total logging, current and for all time
Mark Salyzyn34facab2014-02-06 14:48:50 -0800213
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700214 android::String8 output("size/num");
215 size_t oldLength;
216 short spaces = 1;
217
218 log_id_for_each(id) {
219 if (!(logMask & (1 << id))) {
Mark Salyzync8a576c2014-04-04 16:35:59 -0700220 continue;
221 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700222 oldLength = output.length();
Mark Salyzync8a576c2014-04-04 16:35:59 -0700223 if (spaces < 0) {
224 spaces = 0;
225 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700226 output.appendFormat("%*s%s", spaces, "", android_log_id_to_name(id));
227 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800228 }
229
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700230 spaces = 4;
231 output.appendFormat("\nTotal");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800232
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700233 log_id_for_each(id) {
234 if (!(logMask & (1 << id))) {
235 continue;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800236 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700237 oldLength = output.length();
238 if (spaces < 0) {
239 spaces = 0;
240 }
241 output.appendFormat("%*s%zu/%zu", spaces, "",
242 sizesTotal(id), elementsTotal(id));
243 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800244 }
245
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700246 spaces = 6;
247 output.appendFormat("\nNow");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800248
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700249 log_id_for_each(id) {
250 if (!(logMask & (1 << id))) {
Mark Salyzyn34facab2014-02-06 14:48:50 -0800251 continue;
252 }
253
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700254 size_t els = elements(id);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800255 if (els) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700256 oldLength = output.length();
Mark Salyzyne457b742014-02-19 17:18:31 -0800257 if (spaces < 0) {
258 spaces = 0;
259 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700260 output.appendFormat("%*s%zu/%zu", spaces, "", sizes(id), els);
261 spaces -= output.length() - oldLength;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800262 }
263 spaces += spaces_total;
264 }
265
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700266 // Report on Chattiest
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700267
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700268 // Chattiest by application (UID)
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700269 static const size_t maximum_sorted_entries = 32;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700270 log_id_for_each(id) {
271 if (!(logMask & (1 << id))) {
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700272 continue;
273 }
274
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700275 bool headerPrinted = false;
276 std::unique_ptr<const UidEntry *[]> sorted = sort(maximum_sorted_entries, id);
277 ssize_t index = -1;
278 while ((index = uidTable_t::next(index, sorted, maximum_sorted_entries)) >= 0) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700279 const UidEntry *entry = sorted[index];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700280 uid_t u = entry->getKey();
281 if ((uid != AID_ROOT) && (u != uid)) {
282 continue;
283 }
284
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700285 if (!headerPrinted) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700286 output.appendFormat("\n\n");
287 android::String8 name("");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700288 if (uid == AID_ROOT) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700289 name.appendFormat(
290 "Chattiest UIDs in %s log buffer:",
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700291 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700292 } else {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700293 name.appendFormat(
294 "Logging for your UID in %s log buffer:",
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700295 android_log_id_to_name(id));
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700296 }
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700297 android::String8 size("Size");
298 android::String8 pruned("Pruned");
Mark Salyzynae769232015-03-17 17:17:25 -0700299 if (!worstUidEnabledForLogid(id)) {
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700300 pruned.setTo("");
301 }
302 format_line(output, name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700303
304 name.setTo("UID PACKAGE");
305 size.setTo("BYTES");
306 pruned.setTo("LINES");
307 if (!worstUidEnabledForLogid(id)) {
308 pruned.setTo("");
309 }
310 format_line(output, name, size, pruned);
311
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700312 headerPrinted = true;
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700313 }
314
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700315 android::String8 name("");
316 name.appendFormat("%u", u);
317 char *n = uidToName(u);
318 if (n) {
319 name.appendFormat("%*s%s", (int)std::max(6 - name.length(), (size_t)1), "", n);
320 free(n);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700321 }
322
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700323 android::String8 size("");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700324 size.appendFormat("%zu", entry->getSizes());
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700325
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700326 android::String8 pruned("");
327 size_t dropped = entry->getDropped();
328 if (dropped) {
329 pruned.appendFormat("%zu", dropped);
330 }
331
332 format_line(output, name, size, pruned);
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700333 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700334 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700335
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700336 if (enable) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700337 // Pid table
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700338 bool headerPrinted = false;
339 std::unique_ptr<const PidEntry *[]> sorted = pidTable.sort(maximum_sorted_entries);
340 ssize_t index = -1;
341 while ((index = pidTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
342 const PidEntry *entry = sorted[index];
343 uid_t u = entry->getUid();
344 if ((uid != AID_ROOT) && (u != uid)) {
345 continue;
346 }
347
348 if (!headerPrinted) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700349 output.appendFormat("\n\n");
350 android::String8 name("");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700351 if (uid == AID_ROOT) {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700352 name.appendFormat("Chattiest PIDs:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700353 } else {
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700354 name.appendFormat("Logging for this PID:");
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700355 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700356 android::String8 size("Size");
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700357 android::String8 pruned("Pruned");
358 format_line(output, name, size, pruned);
Mark Salyzyn5720d2c2015-04-21 07:43:16 -0700359
360 name.setTo(" PID/UID COMMAND LINE");
361 size.setTo("BYTES");
362 pruned.setTo("LINES");
363 format_line(output, name, size, pruned);
364
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700365 headerPrinted = true;
366 }
367
368 android::String8 name("");
369 name.appendFormat("%5u/%u", entry->getKey(), u);
370 const char *n = entry->getName();
371 if (n) {
372 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", n);
373 } else {
374 char *un = uidToName(u);
375 if (un) {
376 name.appendFormat("%*s%s", (int)std::max(12 - name.length(), (size_t)1), "", un);
377 free(un);
378 }
379 }
380
381 android::String8 size("");
382 size.appendFormat("%zu", entry->getSizes());
383
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700384 android::String8 pruned("");
385 size_t dropped = entry->getDropped();
386 if (dropped) {
387 pruned.appendFormat("%zu", dropped);
388 }
389
390 format_line(output, name, size, pruned);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700391 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700392 }
393
Mark Salyzyn344bff42015-04-13 14:24:45 -0700394 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
395 // Tag table
396 bool headerPrinted = false;
397 std::unique_ptr<const TagEntry *[]> sorted = tagTable.sort(maximum_sorted_entries);
398 ssize_t index = -1;
399 while ((index = tagTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
400 const TagEntry *entry = sorted[index];
401 uid_t u = entry->getUid();
402 if ((uid != AID_ROOT) && (u != uid)) {
403 continue;
404 }
405
406 android::String8 pruned("");
407
408 if (!headerPrinted) {
409 output.appendFormat("\n\n");
410 android::String8 name("Chattiest events log buffer TAGs:");
411 android::String8 size("Size");
412 format_line(output, name, size, pruned);
413
414 name.setTo(" TAG/UID TAGNAME");
415 size.setTo("BYTES");
416 format_line(output, name, size, pruned);
417
418 headerPrinted = true;
419 }
420
421 android::String8 name("");
422 if (u == (uid_t)-1) {
423 name.appendFormat("%7u", entry->getKey());
424 } else {
425 name.appendFormat("%7u/%u", entry->getKey(), u);
426 }
427 const char *n = entry->getName();
428 if (n) {
429 name.appendFormat("%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", n);
430 }
431
432 android::String8 size("");
433 size.appendFormat("%zu", entry->getSizes());
434
435 format_line(output, name, size, pruned);
436 }
437 }
438
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700439 *buf = strdup(output.string());
Mark Salyzyn34facab2014-02-06 14:48:50 -0800440}
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700441
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700442namespace android {
443
444uid_t pidToUid(pid_t pid) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700445 char buffer[512];
446 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
447 FILE *fp = fopen(buffer, "r");
448 if (fp) {
449 while (fgets(buffer, sizeof(buffer), fp)) {
450 int uid;
Mark Salyzync32afdf2015-04-14 13:07:29 -0700451 if (sscanf(buffer, "Uid: %d", &uid) == 1) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700452 fclose(fp);
453 return uid;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700454 }
455 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700456 fclose(fp);
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700457 }
Mark Salyzyne3aeeee2015-03-17 07:56:32 -0700458 return AID_LOGD; // associate this with the logger
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700459}
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700460
461}
462
463uid_t LogStatistics::pidToUid(pid_t pid) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700464 return pidTable.entryAt(pidTable.add(pid)).getUid();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700465}
466
467// caller must free character string
468char *LogStatistics::pidToName(pid_t pid) {
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700469 const char *name = pidTable.entryAt(pidTable.add(pid)).getName();
470 if (!name) {
471 return NULL;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700472 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700473 return strdup(name);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700474}