| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 
|  | 2 // Use of this source code is governed by a BSD-style license that can be | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 #include "procfs_utils.h" | 
|  | 6 | 
|  | 7 #include <stdio.h> | 
|  | 8 #include <string.h> | 
|  | 9 | 
|  | 10 #include "file_utils.h" | 
|  | 11 #include "logging.h" | 
|  | 12 | 
|  | 13 using file_utils::ForEachPidInProcPath; | 
|  | 14 using file_utils::ReadProcFile; | 
|  | 15 using file_utils::ReadProcFileTrimmed; | 
|  | 16 | 
|  | 17 namespace procfs_utils { | 
|  | 18 | 
|  | 19 namespace { | 
|  | 20 | 
|  | 21 const char kJavaAppPrefix[] = "/system/bin/app_process"; | 
|  | 22 const char kZygotePrefix[] = "zygote"; | 
|  | 23 | 
|  | 24 inline void ReadProcString(int pid, const char* path, char* buf, size_t size) { | 
|  | 25   if (!file_utils::ReadProcFileTrimmed(pid, path, buf, size)) | 
|  | 26     buf[0] = '\0'; | 
|  | 27 } | 
|  | 28 | 
|  | 29 inline void ReadExePath(int pid, char* buf, size_t size) { | 
|  | 30   char exe_path[64]; | 
|  | 31   sprintf(exe_path, "/proc/%d/exe", pid); | 
|  | 32   ssize_t res = readlink(exe_path, buf, size - 1); | 
|  | 33   if (res >= 0) | 
|  | 34     buf[res] = '\0'; | 
|  | 35   else | 
|  | 36     buf[0] = '\0'; | 
|  | 37 } | 
|  | 38 | 
|  | 39 inline bool IsApp(const char* name, const char* exe) { | 
|  | 40   return strncmp(exe, kJavaAppPrefix, sizeof(kJavaAppPrefix) - 1) == 0 && | 
|  | 41          strncmp(name, kZygotePrefix, sizeof(kZygotePrefix) - 1) != 0; | 
|  | 42 } | 
|  | 43 | 
|  | 44 }  // namespace | 
|  | 45 | 
|  | 46 int ReadTgid(int pid) { | 
|  | 47   static const char kTgid[] = "\nTgid:"; | 
|  | 48   char buf[512]; | 
|  | 49   ssize_t rsize = ReadProcFile(pid, "status", buf, sizeof(buf)); | 
|  | 50   if (rsize <= 0) | 
|  | 51     return -1; | 
|  | 52   const char* tgid_line = strstr(buf, kTgid); | 
|  | 53   CHECK(tgid_line); | 
|  | 54   return atoi(tgid_line + sizeof(kTgid) - 1); | 
|  | 55 } | 
|  | 56 | 
|  | 57 std::unique_ptr<ProcessInfo> ReadProcessInfo(int pid) { | 
|  | 58   ProcessInfo* process = new ProcessInfo(); | 
|  | 59   process->pid = pid; | 
|  | 60   ReadProcString(pid, "cmdline", process->name, sizeof(process->name)); | 
|  | 61   if (process->name[0] != 0) { | 
|  | 62     ReadExePath(pid, process->exe, sizeof(process->exe)); | 
|  | 63     process->is_app = IsApp(process->name, process->exe); | 
|  | 64   } else { | 
|  | 65     ReadProcString(pid, "comm", process->name, sizeof(process->name)); | 
|  | 66     CHECK(process->name[0]); | 
|  | 67     process->in_kernel = true; | 
|  | 68   } | 
|  | 69   return std::unique_ptr<ProcessInfo>(process); | 
|  | 70 } | 
|  | 71 | 
|  | 72 void ReadProcessThreads(ProcessInfo* process) { | 
|  | 73   if (process->in_kernel) | 
|  | 74     return; | 
|  | 75 | 
|  | 76   char tasks_path[64]; | 
|  | 77   sprintf(tasks_path, "/proc/%d/task", process->pid); | 
|  | 78   ForEachPidInProcPath(tasks_path, [process](int tid) { | 
|  | 79     if (process->threads.count(tid)) | 
|  | 80       return; | 
|  | 81     ThreadInfo thread = { tid, "" }; | 
|  | 82     char task_comm[64]; | 
|  | 83     sprintf(task_comm, "task/%d/comm", tid); | 
|  | 84     ReadProcString(process->pid, task_comm, thread.name, sizeof(thread.name)); | 
|  | 85     if (thread.name[0] == '\0' && process->is_app) | 
|  | 86       strcpy(thread.name, "UI Thread"); | 
|  | 87     process->threads[tid] = thread; | 
|  | 88   }); | 
|  | 89 } | 
|  | 90 | 
|  | 91 bool ReadOomStats(ProcessSnapshot* snapshot) { | 
|  | 92   char buf[64]; | 
|  | 93   if (ReadProcFileTrimmed(snapshot->pid, "oom_score", buf, sizeof(buf))) | 
|  | 94     snapshot->oom_score = atoi(buf); | 
|  | 95   else | 
|  | 96     return false; | 
|  | 97   if (ReadProcFileTrimmed(snapshot->pid, "oom_score_adj", buf, sizeof(buf))) | 
|  | 98     snapshot->oom_score_adj = atoi(buf); | 
|  | 99   else | 
|  | 100     return false; | 
|  | 101   return true; | 
|  | 102 } | 
|  | 103 | 
|  | 104 bool ReadPageFaultsAndCpuTimeStats(ProcessSnapshot* snapshot) { | 
|  | 105   char buf[512]; | 
|  | 106   if (!ReadProcFileTrimmed(snapshot->pid, "stat", buf, sizeof(buf))) | 
|  | 107     return false; | 
|  | 108   int ret = sscanf(buf, | 
|  | 109       "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %lu %*lu %lu %*lu %lu %lu", | 
|  | 110       &snapshot->minor_faults, &snapshot->major_faults, | 
|  | 111       &snapshot->utime, &snapshot->stime); | 
|  | 112   CHECK(ret == 4); | 
|  | 113   return true; | 
|  | 114 } | 
|  | 115 | 
|  | 116 | 
|  | 117 }  // namespace procfs_utils | 
| OLD | NEW | 
|---|