LCOV - code coverage report
Current view: top level - ipc/chromium/src/base - process_util.h (source / functions) Hit Total Coverage
Test: output.info Lines: 10 21 47.6 %
Date: 2017-07-14 16:53:18 Functions: 3 4 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : // Copyright (c) 2009 The Chromium Authors. All rights reserved.
       4             : // Use of this source code is governed by a BSD-style license that can be
       5             : // found in the LICENSE file.
       6             : 
       7             : // This file/namespace contains utility functions for enumerating, ending and
       8             : // computing statistics of processes.
       9             : 
      10             : #ifndef BASE_PROCESS_UTIL_H_
      11             : #define BASE_PROCESS_UTIL_H_
      12             : 
      13             : #include "base/basictypes.h"
      14             : 
      15             : #if defined(OS_WIN)
      16             : #include <windows.h>
      17             : #include <tlhelp32.h>
      18             : #include <io.h>
      19             : #ifndef STDOUT_FILENO
      20             : #define STDOUT_FILENO 1
      21             : #endif
      22             : #elif defined(OS_LINUX) || defined(__GLIBC__)
      23             : #include <dirent.h>
      24             : #include <limits.h>
      25             : #include <sys/types.h>
      26             : #elif defined(OS_MACOSX)
      27             : #include <mach/mach.h>
      28             : #endif
      29             : 
      30             : #include <map>
      31             : #include <string>
      32             : #include <vector>
      33             : #include <stdio.h>
      34             : #include <stdlib.h>
      35             : #ifndef OS_WIN
      36             : #include <unistd.h>
      37             : #endif
      38             : 
      39             : #include "base/child_privileges.h"
      40             : #include "base/command_line.h"
      41             : #include "base/process.h"
      42             : 
      43             : #if defined(OS_WIN)
      44             : typedef PROCESSENTRY32 ProcessEntry;
      45             : typedef IO_COUNTERS IoCounters;
      46             : #elif defined(OS_POSIX)
      47             : // TODO(port): we should not rely on a Win32 structure.
      48             : struct ProcessEntry {
      49             :   int pid;
      50             :   int ppid;
      51             :   char szExeFile[_POSIX_PATH_MAX + 1];
      52             : };
      53             : 
      54             : struct IoCounters {
      55             :   unsigned long long ReadOperationCount;
      56             :   unsigned long long WriteOperationCount;
      57             :   unsigned long long OtherOperationCount;
      58             :   unsigned long long ReadTransferCount;
      59             :   unsigned long long WriteTransferCount;
      60             :   unsigned long long OtherTransferCount;
      61             : };
      62             : 
      63             : #include "base/file_descriptor_shuffle.h"
      64             : #endif
      65             : 
      66             : #if defined(OS_MACOSX)
      67             : struct kinfo_proc;
      68             : #endif
      69             : 
      70             : namespace base {
      71             : 
      72             : // These can be used in a 32-bit bitmask.
      73             : enum ProcessArchitecture {
      74             :   PROCESS_ARCH_I386 = 0x1,
      75             :   PROCESS_ARCH_X86_64 = 0x2,
      76             :   PROCESS_ARCH_PPC = 0x4,
      77             :   PROCESS_ARCH_ARM = 0x8,
      78             :   PROCESS_ARCH_MIPS = 0x10,
      79             :   PROCESS_ARCH_ARM64 = 0x20
      80             : };
      81             : 
      82           4 : inline ProcessArchitecture GetCurrentProcessArchitecture()
      83             : {
      84             :   base::ProcessArchitecture currentArchitecture;
      85             : #if defined(ARCH_CPU_X86)
      86             :   currentArchitecture = base::PROCESS_ARCH_I386;
      87             : #elif defined(ARCH_CPU_X86_64)
      88           4 :   currentArchitecture = base::PROCESS_ARCH_X86_64;
      89             : #elif defined(ARCH_CPU_PPC)
      90             :   currentArchitecture = base::PROCESS_ARCH_PPC;
      91             : #elif defined(ARCH_CPU_ARMEL)
      92             :   currentArchitecture = base::PROCESS_ARCH_ARM;
      93             : #elif defined(ARCH_CPU_MIPS)
      94             :   currentArchitecture = base::PROCESS_ARCH_MIPS;
      95             : #elif defined(ARCH_CPU_ARM64)
      96             :   currentArchitecture = base::PROCESS_ARCH_ARM64;
      97             : #endif
      98           4 :   return currentArchitecture;
      99             : }
     100             : 
     101             : // A minimalistic but hopefully cross-platform set of exit codes.
     102             : // Do not change the enumeration values or you will break third-party
     103             : // installers.
     104             : enum {
     105             :   PROCESS_END_NORMAL_TERMINATON = 0,
     106             :   PROCESS_END_KILLED_BY_USER    = 1,
     107             :   PROCESS_END_PROCESS_WAS_HUNG  = 2
     108             : };
     109             : 
     110             : // Returns the id of the current process.
     111             : ProcessId GetCurrentProcId();
     112             : 
     113             : // Returns the ProcessHandle of the current process.
     114             : ProcessHandle GetCurrentProcessHandle();
     115             : 
     116             : // Converts a PID to a process handle. This handle must be closed by
     117             : // CloseProcessHandle when you are done with it. Returns true on success.
     118             : bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle);
     119             : 
     120             : // Converts a PID to a process handle. On Windows the handle is opened
     121             : // with more access rights and must only be used by trusted code.
     122             : // You have to close returned handle using CloseProcessHandle. Returns true
     123             : // on success.
     124             : bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle);
     125             : 
     126             : // Closes the process handle opened by OpenProcessHandle.
     127             : void CloseProcessHandle(ProcessHandle process);
     128             : 
     129             : // Returns the unique ID for the specified process. This is functionally the
     130             : // same as Windows' GetProcessId(), but works on versions of Windows before
     131             : // Win XP SP1 as well.
     132             : ProcessId GetProcId(ProcessHandle process);
     133             : 
     134             : #if defined(OS_POSIX)
     135             : // Sets all file descriptors to close on exec except for stdin, stdout
     136             : // and stderr.
     137             : // TODO(agl): remove this function
     138             : // WARNING: do not use. It's inherently race-prone in the face of
     139             : // multi-threading.
     140             : void SetAllFDsToCloseOnExec();
     141             : // Close all file descriptors, expect those which are a destination in the
     142             : // given multimap. Only call this function in a child process where you know
     143             : // that there aren't any other threads.
     144             : void CloseSuperfluousFds(const base::InjectiveMultimap& saved_map);
     145             : #endif
     146             : 
     147             : #if defined(OS_WIN)
     148             : // Runs the given application name with the given command line. Normally, the
     149             : // first command line argument should be the path to the process, and don't
     150             : // forget to quote it.
     151             : //
     152             : // If wait is true, it will block and wait for the other process to finish,
     153             : // otherwise, it will just continue asynchronously.
     154             : //
     155             : // Example (including literal quotes)
     156             : //  cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
     157             : //
     158             : // If process_handle is non-NULL, the process handle of the launched app will be
     159             : // stored there on a successful launch.
     160             : // NOTE: In this case, the caller is responsible for closing the handle so
     161             : //       that it doesn't leak!
     162             : bool LaunchApp(const std::wstring& cmdline,
     163             :                bool wait, bool start_hidden, ProcessHandle* process_handle);
     164             : #elif defined(OS_POSIX)
     165             : // Runs the application specified in argv[0] with the command line argv.
     166             : // Before launching all FDs open in the parent process will be marked as
     167             : // close-on-exec.  |fds_to_remap| defines a mapping of src fd->dest fd to
     168             : // propagate FDs into the child process.
     169             : //
     170             : // As above, if wait is true, execute synchronously. The pid will be stored
     171             : // in process_handle if that pointer is non-null.
     172             : //
     173             : // Note that the first argument in argv must point to the filename,
     174             : // and must be fully specified.
     175             : typedef std::vector<std::pair<int, int> > file_handle_mapping_vector;
     176             : bool LaunchApp(const std::vector<std::string>& argv,
     177             :                const file_handle_mapping_vector& fds_to_remap,
     178             :                bool wait, ProcessHandle* process_handle);
     179             : 
     180             : typedef std::map<std::string, std::string> environment_map;
     181             : bool LaunchApp(const std::vector<std::string>& argv,
     182             :                const file_handle_mapping_vector& fds_to_remap,
     183             :                const environment_map& env_vars_to_set,
     184             :                ChildPrivileges privs,
     185             :                bool wait, ProcessHandle* process_handle,
     186             :                ProcessArchitecture arch=GetCurrentProcessArchitecture());
     187             : bool LaunchApp(const std::vector<std::string>& argv,
     188             :                const file_handle_mapping_vector& fds_to_remap,
     189             :                const environment_map& env_vars_to_set,
     190             :                bool wait, ProcessHandle* process_handle,
     191             :                ProcessArchitecture arch=GetCurrentProcessArchitecture());
     192             : #endif
     193             : 
     194             : // Adjust the privileges of this process to match |privs|.  Only
     195             : // returns if privileges were successfully adjusted.
     196             : void SetCurrentProcessPrivileges(ChildPrivileges privs);
     197             : 
     198             : // Executes the application specified by cl. This function delegates to one
     199             : // of the above two platform-specific functions.
     200             : bool LaunchApp(const CommandLine& cl,
     201             :                bool wait, bool start_hidden, ProcessHandle* process_handle);
     202             : 
     203             : // Used to filter processes by process ID.
     204             : class ProcessFilter {
     205             :  public:
     206             :   // Returns true to indicate set-inclusion and false otherwise.  This method
     207             :   // should not have side-effects and should be idempotent.
     208             :   virtual bool Includes(ProcessId pid, ProcessId parent_pid) const = 0;
     209             :   virtual ~ProcessFilter() { }
     210             : };
     211             : 
     212             : // Attempts to kill the process identified by the given process
     213             : // entry structure, giving it the specified exit code. If |wait| is true, wait
     214             : // for the process to be actually terminated before returning.
     215             : // Returns true if this is successful, false otherwise.
     216             : bool KillProcess(ProcessHandle process, int exit_code, bool wait);
     217             : 
     218             : // Get the termination status (exit code) of the process and return true if the
     219             : // status indicates the process crashed. |child_exited| is set to true iff the
     220             : // child process has terminated. (|child_exited| may be NULL.)
     221             : //
     222             : // On Windows, it is an error to call this if the process hasn't terminated
     223             : // yet. On POSIX, |child_exited| is set correctly since we detect terminate in
     224             : // a different manner on POSIX.
     225             : bool DidProcessCrash(bool* child_exited, ProcessHandle handle);
     226             : 
     227             : // Provides performance metrics for a specified process (CPU usage, memory and
     228             : // IO counters). To use it, invoke CreateProcessMetrics() to get an instance
     229             : // for a specific process, then access the information with the different get
     230             : // methods.
     231             : class ProcessMetrics {
     232             :  public:
     233             :   // Creates a ProcessMetrics for the specified process.
     234             :   // The caller owns the returned object.
     235             :   static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
     236             : 
     237             :   ~ProcessMetrics();
     238             : 
     239             :   // Returns the CPU usage in percent since the last time this method was
     240             :   // called. The first time this method is called it returns 0 and will return
     241             :   // the actual CPU info on subsequent calls.
     242             :   // Note that on multi-processor machines, the CPU usage value is for all
     243             :   // CPUs. So if you have 2 CPUs and your process is using all the cycles
     244             :   // of 1 CPU and not the other CPU, this method returns 50.
     245             :   int GetCPUUsage();
     246             : 
     247             :  private:
     248             :   explicit ProcessMetrics(ProcessHandle process);
     249             : 
     250             :   ProcessHandle process_;
     251             : 
     252             :   int processor_count_;
     253             : 
     254             :   // Used to store the previous times so we can compute the CPU usage.
     255             :   int64_t last_time_;
     256             :   int64_t last_system_time_;
     257             : 
     258             :   DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics);
     259             : };
     260             : 
     261             : }  // namespace base
     262             : 
     263             : namespace mozilla {
     264             : 
     265             : class EnvironmentLog
     266             : {
     267             : public:
     268           3 :   explicit EnvironmentLog(const char* varname) {
     269           3 :     const char *e = getenv(varname);
     270           3 :     if (e && *e) {
     271           0 :       fname_ = e;
     272             :     }
     273           3 :   }
     274             : 
     275           0 :   ~EnvironmentLog() {}
     276             : 
     277           3 :   void print(const char* format, ...) {
     278           3 :     if (!fname_.size())
     279           6 :       return;
     280             : 
     281             :     FILE* f;
     282           0 :     if (fname_.compare("-") == 0) {
     283           0 :       f = fdopen(dup(STDOUT_FILENO), "a");
     284             :     } else {
     285           0 :       f = fopen(fname_.c_str(), "a");
     286             :     }
     287             : 
     288           0 :     if (!f)
     289           0 :       return;
     290             : 
     291             :     va_list a;
     292           0 :     va_start(a, format);
     293           0 :     vfprintf(f, format, a);
     294           0 :     va_end(a);
     295           0 :     fclose(f);
     296             :   }
     297             : 
     298             : private:
     299             :   std::string fname_;
     300             : 
     301             :   DISALLOW_EVIL_CONSTRUCTORS(EnvironmentLog);
     302             : };
     303             : 
     304             : } // namespace mozilla
     305             : 
     306             : #if defined(OS_WIN)
     307             : // Undo the windows.h damage
     308             : #undef GetMessage
     309             : #undef CreateEvent
     310             : #undef GetClassName
     311             : #undef GetBinaryType
     312             : #undef RemoveDirectory
     313             : #endif
     314             : 
     315             : #endif  // BASE_PROCESS_UTIL_H_

Generated by: LCOV version 1.13