Home | History | Annotate | Download | only in jni
      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 "process_info.h"
      6 
      7 #include <ctype.h>
      8 #include <dirent.h>
      9 #include <stdio.h>
     10 #include <stdlib.h>
     11 #include <sys/types.h>
     12 
     13 #include "file_utils.h"
     14 #include "logging.h"
     15 
     16 ProcessInfo::ProcessInfo(int pid) : memory_(pid), pid_(pid) {}
     17 
     18 bool ProcessInfo::IsProcess(int pid) {
     19   char buf[256];
     20   ssize_t rsize = file_utils::ReadProcFile(pid, "status", buf, sizeof(buf));
     21   if (rsize <= 0)
     22     return false;
     23   const char kTgid[] = "\nTgid:";
     24   const char* tgid_line = strstr(buf, kTgid);
     25   CHECK(tgid_line);
     26   int tgid = 0;
     27   if (sscanf(tgid_line + strlen(kTgid), "%d", &tgid) != 1)
     28     CHECK(false);
     29   return tgid == pid;
     30 }
     31 
     32 bool ProcessInfo::ReadProcessName() {
     33   if (!file_utils::ReadProcFileTrimmed(pid_, "cmdline", name_, sizeof(name_)))
     34     return false;
     35 
     36   // Fallback on "comm" for kernel threads.
     37   if (strlen(name_) == 0) {
     38     if (!file_utils::ReadProcFileTrimmed(pid_, "comm", name_, sizeof(name_)))
     39       return false;
     40   }
     41 
     42   // Get also the exe path, to distinguish system vs java apps and bitness.
     43   char exe_path[64];
     44   sprintf(exe_path, "/proc/%d/exe", pid_);
     45   exe_[0] = '\0';
     46   ssize_t res = readlink(exe_path, exe_, sizeof(exe_) - 1);
     47   if (res >= 0)
     48     exe_[res] = '\0';
     49 
     50   return true;
     51 }
     52 
     53 bool ProcessInfo::ReadThreadNames() {
     54   char tasks_path[64];
     55   sprintf(tasks_path, "/proc/%d/task", pid_);
     56   CHECK(threads_.empty());
     57   ThreadInfoMap* threads = &threads_;
     58   const int pid = pid_;
     59   file_utils::ForEachPidInProcPath(tasks_path, [pid, threads](int tid) {
     60     char comm[64];
     61     std::unique_ptr<ThreadInfo> thread_info(new ThreadInfo());
     62     sprintf(comm, "task/%d/comm", tid);
     63     if (!file_utils::ReadProcFileTrimmed(pid, comm, thread_info->name,
     64                                          sizeof(thread_info->name))) {
     65       return;
     66     }
     67     (*threads)[tid] = std::move(thread_info);
     68   });
     69   return true;
     70 }
     71 
     72 bool ProcessInfo::ReadOOMStats() {
     73   char buf[512];
     74   if (file_utils::ReadProcFileTrimmed(pid_, "oom_adj", buf, sizeof(buf)))
     75     oom_adj_ = atoi(buf);
     76   else
     77     return false;
     78 
     79   if (file_utils::ReadProcFileTrimmed(pid_, "oom_score", buf, sizeof(buf)))
     80     oom_score_ = atoi(buf);
     81   else
     82     return false;
     83 
     84   if (file_utils::ReadProcFileTrimmed(pid_, "oom_score_adj", buf, sizeof(buf)))
     85     oom_score_adj_ = atoi(buf);
     86   else
     87     return false;
     88 
     89   return true;
     90 }
     91 
     92 bool ProcessInfo::ReadPageFaultsAndCPUTimeStats() {
     93   char buf[512];
     94   if (!file_utils::ReadProcFileTrimmed(pid_, "stat", buf, sizeof(buf)))
     95     return false;
     96   int ret = sscanf(buf,
     97                    "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %lu %*lu "
     98                    "%lu %*lu %lu %lu %*ld %*ld %*ld %*ld %*ld %*ld %llu",
     99                    &minflt_, &majflt_, &utime_, &stime_, &start_time_);
    100   CHECK(ret == 5);
    101   return true;
    102 }
    103