blob: fdb2576d658eddfe035e0468a67d8754ee7b70ff [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 Salyzyn9a038632014-04-07 07:05:40 -070017#include <fcntl.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070018#include <stdio.h>
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070019#include <string.h>
20#include <unistd.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080021
22#include <log/logger.h>
Mark Salyzyn34facab2014-02-06 14:48:50 -080023
24#include "LogStatistics.h"
25
Mark Salyzyn77187782015-05-12 15:21:31 -070026LogStatistics::LogStatistics() : enable(false) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070027 log_id_for_each(id) {
28 mSizes[id] = 0;
29 mElements[id] = 0;
Mark Salyzyn58b8be82015-09-30 07:40:09 -070030 mDroppedElements[id] = 0;
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070031 mSizesTotal[id] = 0;
32 mElementsTotal[id] = 0;
Mark Salyzyn34facab2014-02-06 14:48:50 -080033 }
34}
35
Mark Salyzyn720f6d12015-03-16 08:26:05 -070036namespace android {
37
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070038// caller must own and free character string
Mark Salyzyn81b3eab2015-04-13 14:24:45 -070039char *pidToName(pid_t pid) {
Mark Salyzyn9a038632014-04-07 07:05:40 -070040 char *retval = NULL;
Mark Salyzynae4d9282014-10-15 08:49:39 -070041 if (pid == 0) { // special case from auditd/klogd for kernel
42 retval = strdup("logd");
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070043 } else {
Mark Salyzyn9a038632014-04-07 07:05:40 -070044 char buffer[512];
45 snprintf(buffer, sizeof(buffer), "/proc/%u/cmdline", pid);
46 int fd = open(buffer, O_RDONLY);
47 if (fd >= 0) {
48 ssize_t ret = read(fd, buffer, sizeof(buffer));
49 if (ret > 0) {
50 buffer[sizeof(buffer)-1] = '\0';
51 // frameworks intermediate state
Mark Salyzynddda2122015-10-02 09:22:52 -070052 if (fast<strcmp>(buffer, "<pre-initialized>")) {
Mark Salyzyn9a038632014-04-07 07:05:40 -070053 retval = strdup(buffer);
54 }
55 }
56 close(fd);
57 }
58 }
59 return retval;
60}
61
Mark Salyzyn720f6d12015-03-16 08:26:05 -070062}
63
Mark Salyzyn758058f2015-08-21 16:44:30 -070064void LogStatistics::add(LogBufferElement *element) {
65 log_id_t log_id = element->getLogId();
66 unsigned short size = element->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080067 mSizes[log_id] += size;
68 ++mElements[log_id];
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070069
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -070070 mSizesTotal[log_id] += size;
71 ++mElementsTotal[log_id];
Mark Salyzyn720f6d12015-03-16 08:26:05 -070072
Mark Salyzynae4d9282014-10-15 08:49:39 -070073 if (log_id == LOG_ID_KERNEL) {
74 return;
75 }
76
Mark Salyzyn758058f2015-08-21 16:44:30 -070077 uidTable[log_id].add(element->getUid(), element);
Mark Salyzynae4d9282014-10-15 08:49:39 -070078
Mark Salyzyn720f6d12015-03-16 08:26:05 -070079 if (!enable) {
80 return;
81 }
82
Mark Salyzyn758058f2015-08-21 16:44:30 -070083 pidTable.add(element->getPid(), element);
84 tidTable.add(element->getTid(), element);
Mark Salyzyn344bff42015-04-13 14:24:45 -070085
Mark Salyzyn758058f2015-08-21 16:44:30 -070086 uint32_t tag = element->getTag();
Mark Salyzyn344bff42015-04-13 14:24:45 -070087 if (tag) {
Mark Salyzyn758058f2015-08-21 16:44:30 -070088 tagTable.add(tag, element);
Mark Salyzyn344bff42015-04-13 14:24:45 -070089 }
Mark Salyzyn34facab2014-02-06 14:48:50 -080090}
91
Mark Salyzyn758058f2015-08-21 16:44:30 -070092void LogStatistics::subtract(LogBufferElement *element) {
93 log_id_t log_id = element->getLogId();
94 unsigned short size = element->getMsgLen();
Mark Salyzyn34facab2014-02-06 14:48:50 -080095 mSizes[log_id] -= size;
96 --mElements[log_id];
Mark Salyzyn58b8be82015-09-30 07:40:09 -070097 if (element->getDropped()) {
98 --mDroppedElements[log_id];
99 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700100
Mark Salyzynae4d9282014-10-15 08:49:39 -0700101 if (log_id == LOG_ID_KERNEL) {
102 return;
103 }
104
Mark Salyzyn758058f2015-08-21 16:44:30 -0700105 uidTable[log_id].subtract(element->getUid(), element);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800106
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700107 if (!enable) {
108 return;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800109 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700110
Mark Salyzyn758058f2015-08-21 16:44:30 -0700111 pidTable.subtract(element->getPid(), element);
112 tidTable.subtract(element->getTid(), element);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700113
Mark Salyzyn758058f2015-08-21 16:44:30 -0700114 uint32_t tag = element->getTag();
Mark Salyzyn344bff42015-04-13 14:24:45 -0700115 if (tag) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700116 tagTable.subtract(tag, element);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700117 }
Mark Salyzyn34facab2014-02-06 14:48:50 -0800118}
119
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700120// Atomically set an entry to drop
121// entry->setDropped(1) must follow this call, caller should do this explicitly.
Mark Salyzyn758058f2015-08-21 16:44:30 -0700122void LogStatistics::drop(LogBufferElement *element) {
123 log_id_t log_id = element->getLogId();
124 unsigned short size = element->getMsgLen();
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700125 mSizes[log_id] -= size;
Mark Salyzyn58b8be82015-09-30 07:40:09 -0700126 ++mDroppedElements[log_id];
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700127
Mark Salyzyn758058f2015-08-21 16:44:30 -0700128 uidTable[log_id].drop(element->getUid(), element);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700129
130 if (!enable) {
131 return;
132 }
133
Mark Salyzyn758058f2015-08-21 16:44:30 -0700134 pidTable.drop(element->getPid(), element);
135 tidTable.drop(element->getTid(), element);
Mark Salyzynab0dcf62015-03-16 12:04:09 -0700136}
137
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700138// caller must own and free character string
Mark Salyzyn758058f2015-08-21 16:44:30 -0700139const char *LogStatistics::uidToName(uid_t uid) const {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700140 // Local hard coded favourites
141 if (uid == AID_LOGD) {
142 return strdup("auditd");
Mark Salyzyn34facab2014-02-06 14:48:50 -0800143 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700144
145 // Android hard coded
146 const struct android_id_info *info = android_ids;
147
148 for (size_t i = 0; i < android_id_count; ++i) {
149 if (info->aid == uid) {
150 return strdup(info->name);
151 }
152 ++info;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800153 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700154
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700155 // Parse /data/system/packages.list
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700156 uid_t userId = uid % AID_USER;
Mark Salyzyn758058f2015-08-21 16:44:30 -0700157 const char *name = android::uidToName(userId);
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700158 if (!name && (userId > (AID_SHARED_GID_START - AID_APP))) {
159 name = android::uidToName(userId - (AID_SHARED_GID_START - AID_APP));
160 }
Mark Salyzyn08739ba2015-03-16 08:26:05 -0700161 if (name) {
162 return name;
163 }
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700164
165 // report uid -> pid(s) -> pidToName if unique
Mark Salyzyn758058f2015-08-21 16:44:30 -0700166 for(pidTable_t::const_iterator it = pidTable.begin(); it != pidTable.end(); ++it) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700167 const PidEntry &entry = it->second;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700168
169 if (entry.getUid() == uid) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700170 const char *nameTmp = entry.getName();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700171
Mark Salyzyn758058f2015-08-21 16:44:30 -0700172 if (nameTmp) {
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700173 if (!name) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700174 name = strdup(nameTmp);
175 } else if (fast<strcmp>(name, nameTmp)) {
176 free(const_cast<char *>(name));
Mark Salyzyn023f51f2015-04-29 12:48:45 -0700177 name = NULL;
178 break;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700179 }
180 }
181 }
182 }
183
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700184 // No one
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700185 return name;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800186}
187
Mark Salyzyn758058f2015-08-21 16:44:30 -0700188std::string UidEntry::formatHeader(const std::string &name, log_id_t id) const {
189 bool isprune = worstUidEnabledForLogid(id);
190 return formatLine(android::base::StringPrintf(
191 name.c_str(), android_log_id_to_name(id)),
192 std::string("Size"),
193 std::string(isprune ? "Pruned" : ""))
194 + formatLine(std::string("UID PACKAGE"),
195 std::string("BYTES"),
196 std::string(isprune ? "NUM" : ""));
Mark Salyzyn34facab2014-02-06 14:48:50 -0800197}
198
Mark Salyzyn758058f2015-08-21 16:44:30 -0700199std::string UidEntry::format(const LogStatistics &stat, log_id_t /* id */) const {
200 uid_t uid = getKey();
201 std::string name = android::base::StringPrintf("%u", uid);
202 const char *nameTmp = stat.uidToName(uid);
203 if (nameTmp) {
204 name += android::base::StringPrintf(
205 "%*s%s", (int)std::max(6 - name.length(), (size_t)1),
206 "", nameTmp);
207 free(const_cast<char *>(nameTmp));
208 }
209
210 std::string size = android::base::StringPrintf("%zu", getSizes());
211
212 std::string pruned = "";
213 size_t dropped = getDropped();
214 if (dropped) {
215 pruned = android::base::StringPrintf("%zu", dropped);
216 }
217
218 return formatLine(name, size, pruned);
219}
220
221std::string PidEntry::formatHeader(const std::string &name, log_id_t /* id */) const {
222 return formatLine(name,
223 std::string("Size"),
224 std::string("Pruned"))
225 + formatLine(std::string(" PID/UID COMMAND LINE"),
226 std::string("BYTES"),
227 std::string("NUM"));
228}
229
230std::string PidEntry::format(const LogStatistics &stat, log_id_t /* id */) const {
231 uid_t uid = getUid();
232 std::string name = android::base::StringPrintf("%5u/%u",
233 getKey(), uid);
234 const char *nameTmp = getName();
235 if (nameTmp) {
236 name += android::base::StringPrintf(
237 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
238 "", nameTmp);
239 } else if ((nameTmp = stat.uidToName(uid))) {
240 name += android::base::StringPrintf(
241 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
242 "", nameTmp);
243 free(const_cast<char *>(nameTmp));
244 }
245
246 std::string size = android::base::StringPrintf("%zu",
247 getSizes());
248
249 std::string pruned = "";
250 size_t dropped = getDropped();
251 if (dropped) {
252 pruned = android::base::StringPrintf("%zu", dropped);
253 }
254
255 return formatLine(name, size, pruned);
256}
257
258std::string TidEntry::formatHeader(const std::string &name, log_id_t /* id */) const {
259 return formatLine(name,
260 std::string("Size"),
261 std::string("Pruned"))
262 + formatLine(std::string(" TID/UID COMM"),
263 std::string("BYTES"),
264 std::string("NUM"));
265}
266
267std::string TidEntry::format(const LogStatistics &stat, log_id_t /* id */) const {
268 uid_t uid = getUid();
269 std::string name = android::base::StringPrintf("%5u/%u",
270 getKey(), uid);
271 const char *nameTmp = getName();
272 if (nameTmp) {
273 name += android::base::StringPrintf(
274 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
275 "", nameTmp);
276 } else if ((nameTmp = stat.uidToName(uid))) {
277 // if we do not have a PID name, lets punt to try UID name?
278 name += android::base::StringPrintf(
279 "%*s%s", (int)std::max(12 - name.length(), (size_t)1),
280 "", nameTmp);
281 free(const_cast<char *>(nameTmp));
282 // We tried, better to not have a name at all, we still
283 // have TID/UID by number to report in any case.
284 }
285
286 std::string size = android::base::StringPrintf("%zu",
287 getSizes());
288
289 std::string pruned = "";
290 size_t dropped = getDropped();
291 if (dropped) {
292 pruned = android::base::StringPrintf("%zu", dropped);
293 }
294
295 return formatLine(name, size, pruned);
296}
297
298std::string TagEntry::formatHeader(const std::string &name, log_id_t id) const {
299 bool isprune = worstUidEnabledForLogid(id);
300 return formatLine(name,
301 std::string("Size"),
302 std::string(isprune ? "Prune" : ""))
303 + formatLine(std::string(" TAG/UID TAGNAME"),
304 std::string("BYTES"),
305 std::string(isprune ? "NUM" : ""));
306}
307
308std::string TagEntry::format(const LogStatistics & /* stat */, log_id_t /* id */) const {
309 std::string name;
310 uid_t uid = getUid();
311 if (uid == (uid_t)-1) {
312 name = android::base::StringPrintf("%7u",
313 getKey());
314 } else {
315 name = android::base::StringPrintf("%7u/%u",
316 getKey(), uid);
317 }
318 const char *nameTmp = getName();
319 if (nameTmp) {
320 name += android::base::StringPrintf(
321 "%*s%s", (int)std::max(14 - name.length(), (size_t)1),
322 "", nameTmp);
323 }
324
325 std::string size = android::base::StringPrintf("%zu",
326 getSizes());
327
328 std::string pruned = "";
329
330 return formatLine(name, size, pruned);
331}
332
333std::string LogStatistics::format(uid_t uid, unsigned int logMask) const {
Mark Salyzyn9a038632014-04-07 07:05:40 -0700334 static const unsigned short spaces_total = 19;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800335
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700336 // Report on total logging, current and for all time
Mark Salyzyn34facab2014-02-06 14:48:50 -0800337
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700338 std::string output = "size/num";
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700339 size_t oldLength;
340 short spaces = 1;
341
342 log_id_for_each(id) {
343 if (!(logMask & (1 << id))) {
Mark Salyzync8a576c2014-04-04 16:35:59 -0700344 continue;
345 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700346 oldLength = output.length();
Mark Salyzync8a576c2014-04-04 16:35:59 -0700347 if (spaces < 0) {
348 spaces = 0;
349 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700350 output += android::base::StringPrintf("%*s%s", spaces, "",
351 android_log_id_to_name(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700352 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800353 }
354
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700355 spaces = 4;
Mark Salyzyn758058f2015-08-21 16:44:30 -0700356 output += "\nTotal";
Mark Salyzyn34facab2014-02-06 14:48:50 -0800357
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700358 log_id_for_each(id) {
359 if (!(logMask & (1 << id))) {
360 continue;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800361 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700362 oldLength = output.length();
363 if (spaces < 0) {
364 spaces = 0;
365 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700366 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
367 sizesTotal(id),
368 elementsTotal(id));
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700369 spaces += spaces_total + oldLength - output.length();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800370 }
371
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700372 spaces = 6;
Mark Salyzyn758058f2015-08-21 16:44:30 -0700373 output += "\nNow";
Mark Salyzyn34facab2014-02-06 14:48:50 -0800374
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700375 log_id_for_each(id) {
376 if (!(logMask & (1 << id))) {
Mark Salyzyn34facab2014-02-06 14:48:50 -0800377 continue;
378 }
379
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700380 size_t els = elements(id);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800381 if (els) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700382 oldLength = output.length();
Mark Salyzyne457b742014-02-19 17:18:31 -0800383 if (spaces < 0) {
384 spaces = 0;
385 }
Mark Salyzyndecbcd92015-08-19 15:33:01 -0700386 output += android::base::StringPrintf("%*s%zu/%zu", spaces, "",
387 sizes(id), els);
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700388 spaces -= output.length() - oldLength;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800389 }
390 spaces += spaces_total;
391 }
392
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700393 // Report on Chattiest
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700394
Mark Salyzyn758058f2015-08-21 16:44:30 -0700395 std::string name;
396
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700397 // Chattiest by application (UID)
398 log_id_for_each(id) {
399 if (!(logMask & (1 << id))) {
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700400 continue;
401 }
402
Mark Salyzyn758058f2015-08-21 16:44:30 -0700403 name = (uid == AID_ROOT)
404 ? "Chattiest UIDs in %s log buffer:"
405 : "Logging for your UID in %s log buffer:";
406 output += uidTable[id].format(*this, uid, name, id);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700407 }
Mark Salyzyn8e72c532014-03-26 10:46:39 -0700408
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700409 if (enable) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700410 name = (uid == AID_ROOT) ? "Chattiest PIDs:" : "Logging for this PID:";
411 output += pidTable.format(*this, uid, name);
412 name = "Chattiest TIDs:";
413 output += tidTable.format(*this, uid, name);
Mark Salyzyn17ed6792015-04-20 13:35:15 -0700414 }
415
Mark Salyzyn344bff42015-04-13 14:24:45 -0700416 if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
Mark Salyzyn758058f2015-08-21 16:44:30 -0700417 name = "Chattiest events log buffer TAGs:";
418 output += tagTable.format(*this, uid, name, LOG_ID_EVENTS);
Mark Salyzyn344bff42015-04-13 14:24:45 -0700419 }
420
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700421 return output;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800422}
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700423
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700424namespace android {
425
426uid_t pidToUid(pid_t pid) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700427 char buffer[512];
428 snprintf(buffer, sizeof(buffer), "/proc/%u/status", pid);
429 FILE *fp = fopen(buffer, "r");
430 if (fp) {
431 while (fgets(buffer, sizeof(buffer), fp)) {
432 int uid;
Mark Salyzync32afdf2015-04-14 13:07:29 -0700433 if (sscanf(buffer, "Uid: %d", &uid) == 1) {
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700434 fclose(fp);
435 return uid;
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700436 }
437 }
Mark Salyzyn97c1c2b2015-03-10 13:51:35 -0700438 fclose(fp);
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700439 }
Mark Salyzyne3aeeee2015-03-17 07:56:32 -0700440 return AID_LOGD; // associate this with the logger
Mark Salyzyn4ba03872014-04-07 07:15:33 -0700441}
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700442
443}
444
445uid_t LogStatistics::pidToUid(pid_t pid) {
Mark Salyzyn511338d2015-05-19 09:12:30 -0700446 return pidTable.add(pid)->second.getUid();
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700447}
448
449// caller must free character string
Mark Salyzyn758058f2015-08-21 16:44:30 -0700450const char *LogStatistics::pidToName(pid_t pid) const {
451 // An inconvenient truth ... getName() can alter the object
452 pidTable_t &writablePidTable = const_cast<pidTable_t &>(pidTable);
453 const char *name = writablePidTable.add(pid)->second.getName();
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700454 if (!name) {
455 return NULL;
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700456 }
Mark Salyzyn81b3eab2015-04-13 14:24:45 -0700457 return strdup(name);
Mark Salyzyn720f6d12015-03-16 08:26:05 -0700458}