LCOV - code coverage report
Current view: directory - ipc/chromium/src/base - process_util.h (source / functions) Found Hit Coverage
Test: app.info Lines: 3 0 0.0 %
Date: 2012-06-02 Functions: 1 0 0.0 %

       1                 : // Copyright (c) 2009 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                 : // This file/namespace contains utility functions for enumerating, ending and
       6                 : // computing statistics of processes.
       7                 : 
       8                 : #ifndef BASE_PROCESS_UTIL_H_
       9                 : #define BASE_PROCESS_UTIL_H_
      10                 : 
      11                 : #include "base/basictypes.h"
      12                 : 
      13                 : #if defined(OS_WIN)
      14                 : #include <windows.h>
      15                 : #include <tlhelp32.h>
      16                 : #elif defined(OS_LINUX)
      17                 : #include <dirent.h>
      18                 : #include <limits.h>
      19                 : #include <sys/types.h>
      20                 : #elif defined(OS_MACOSX)
      21                 : #include <mach/mach.h>
      22                 : #endif
      23                 : 
      24                 : #include <map>
      25                 : #include <string>
      26                 : #include <vector>
      27                 : 
      28                 : #include "base/command_line.h"
      29                 : #include "base/process.h"
      30                 : 
      31                 : #if defined(OS_WIN)
      32                 : typedef PROCESSENTRY32 ProcessEntry;
      33                 : typedef IO_COUNTERS IoCounters;
      34                 : #elif defined(OS_POSIX)
      35                 : // TODO(port): we should not rely on a Win32 structure.
      36                 : struct ProcessEntry {
      37                 :   int pid;
      38                 :   int ppid;
      39                 :   char szExeFile[NAME_MAX + 1];
      40                 : };
      41                 : 
      42                 : struct IoCounters {
      43                 :   unsigned long long ReadOperationCount;
      44                 :   unsigned long long WriteOperationCount;
      45                 :   unsigned long long OtherOperationCount;
      46                 :   unsigned long long ReadTransferCount;
      47                 :   unsigned long long WriteTransferCount;
      48                 :   unsigned long long OtherTransferCount;
      49                 : };
      50                 : 
      51                 : #include "base/file_descriptor_shuffle.h"
      52                 : #endif
      53                 : 
      54                 : #if defined(OS_MACOSX)
      55                 : struct kinfo_proc;
      56                 : #endif
      57                 : 
      58                 : namespace base {
      59                 : 
      60                 : // These can be used in a 32-bit bitmask.
      61                 : enum ProcessArchitecture {
      62                 :   PROCESS_ARCH_I386 = 0x1,
      63                 :   PROCESS_ARCH_X86_64 = 0x2,
      64                 :   PROCESS_ARCH_PPC = 0x4,
      65                 :   PROCESS_ARCH_ARM = 0x8
      66                 : };
      67                 : 
      68               0 : inline ProcessArchitecture GetCurrentProcessArchitecture()
      69                 : {
      70                 :   base::ProcessArchitecture currentArchitecture;
      71                 : #if defined(ARCH_CPU_X86)
      72               0 :   currentArchitecture = base::PROCESS_ARCH_I386;
      73                 : #elif defined(ARCH_CPU_X86_64)
      74                 :   currentArchitecture = base::PROCESS_ARCH_X86_64;
      75                 : #elif defined(ARCH_CPU_PPC)
      76                 :   currentArchitecture = base::PROCESS_ARCH_PPC;
      77                 : #elif defined(ARCH_CPU_ARMEL)
      78                 :   currentArchitecture = base::PROCESS_ARCH_ARM;
      79                 : #endif
      80               0 :   return currentArchitecture;
      81                 : }
      82                 : 
      83                 : // A minimalistic but hopefully cross-platform set of exit codes.
      84                 : // Do not change the enumeration values or you will break third-party
      85                 : // installers.
      86                 : enum {
      87                 :   PROCESS_END_NORMAL_TERMINATON = 0,
      88                 :   PROCESS_END_KILLED_BY_USER    = 1,
      89                 :   PROCESS_END_PROCESS_WAS_HUNG  = 2
      90                 : };
      91                 : 
      92                 : // Returns the id of the current process.
      93                 : ProcessId GetCurrentProcId();
      94                 : 
      95                 : // Returns the ProcessHandle of the current process.
      96                 : ProcessHandle GetCurrentProcessHandle();
      97                 : 
      98                 : // Converts a PID to a process handle. This handle must be closed by
      99                 : // CloseProcessHandle when you are done with it. Returns true on success.
     100                 : bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle);
     101                 : 
     102                 : // Converts a PID to a process handle. On Windows the handle is opened
     103                 : // with more access rights and must only be used by trusted code.
     104                 : // You have to close returned handle using CloseProcessHandle. Returns true
     105                 : // on success.
     106                 : bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle);
     107                 : 
     108                 : // Closes the process handle opened by OpenProcessHandle.
     109                 : void CloseProcessHandle(ProcessHandle process);
     110                 : 
     111                 : // Returns the unique ID for the specified process. This is functionally the
     112                 : // same as Windows' GetProcessId(), but works on versions of Windows before
     113                 : // Win XP SP1 as well.
     114                 : ProcessId GetProcId(ProcessHandle process);
     115                 : 
     116                 : #if defined(OS_POSIX)
     117                 : // Sets all file descriptors to close on exec except for stdin, stdout
     118                 : // and stderr.
     119                 : // TODO(agl): remove this function
     120                 : // WARNING: do not use. It's inherently race-prone in the face of
     121                 : // multi-threading.
     122                 : void SetAllFDsToCloseOnExec();
     123                 : // Close all file descriptors, expect those which are a destination in the
     124                 : // given multimap. Only call this function in a child process where you know
     125                 : // that there aren't any other threads.
     126                 : void CloseSuperfluousFds(const base::InjectiveMultimap& saved_map);
     127                 : #endif
     128                 : 
     129                 : #if defined(OS_WIN)
     130                 : // Runs the given application name with the given command line. Normally, the
     131                 : // first command line argument should be the path to the process, and don't
     132                 : // forget to quote it.
     133                 : //
     134                 : // If wait is true, it will block and wait for the other process to finish,
     135                 : // otherwise, it will just continue asynchronously.
     136                 : //
     137                 : // Example (including literal quotes)
     138                 : //  cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
     139                 : //
     140                 : // If process_handle is non-NULL, the process handle of the launched app will be
     141                 : // stored there on a successful launch.
     142                 : // NOTE: In this case, the caller is responsible for closing the handle so
     143                 : //       that it doesn't leak!
     144                 : bool LaunchApp(const std::wstring& cmdline,
     145                 :                bool wait, bool start_hidden, ProcessHandle* process_handle);
     146                 : #elif defined(OS_POSIX)
     147                 : // Runs the application specified in argv[0] with the command line argv.
     148                 : // Before launching all FDs open in the parent process will be marked as
     149                 : // close-on-exec.  |fds_to_remap| defines a mapping of src fd->dest fd to
     150                 : // propagate FDs into the child process.
     151                 : //
     152                 : // As above, if wait is true, execute synchronously. The pid will be stored
     153                 : // in process_handle if that pointer is non-null.
     154                 : //
     155                 : // Note that the first argument in argv must point to the filename,
     156                 : // and must be fully specified.
     157                 : typedef std::vector<std::pair<int, int> > file_handle_mapping_vector;
     158                 : bool LaunchApp(const std::vector<std::string>& argv,
     159                 :                const file_handle_mapping_vector& fds_to_remap,
     160                 :                bool wait, ProcessHandle* process_handle);
     161                 : 
     162                 : typedef std::map<std::string, std::string> environment_map;
     163                 : bool LaunchApp(const std::vector<std::string>& argv,
     164                 :                const file_handle_mapping_vector& fds_to_remap,
     165                 :                const environment_map& env_vars_to_set,
     166                 :                bool wait, ProcessHandle* process_handle,
     167                 :                ProcessArchitecture arch=GetCurrentProcessArchitecture());
     168                 : #endif
     169                 : 
     170                 : // Executes the application specified by cl. This function delegates to one
     171                 : // of the above two platform-specific functions.
     172                 : bool LaunchApp(const CommandLine& cl,
     173                 :                bool wait, bool start_hidden, ProcessHandle* process_handle);
     174                 : 
     175                 : #if defined(OS_WIN)
     176                 : // Executes the application specified by |cmd_line| and copies the contents
     177                 : // printed to the standard output to |output|, which should be non NULL.
     178                 : // Blocks until the started process terminates.
     179                 : // Returns true if the application was run successfully, false otherwise.
     180                 : bool GetAppOutput(const std::wstring& cmd_line, std::string* output);
     181                 : #elif defined(OS_POSIX)
     182                 : // Executes the application specified by |cl| and wait for it to exit. Stores
     183                 : // the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true
     184                 : // on success (application launched and exited cleanly, with exit code
     185                 : // indicating success). |output| is modified only when the function finished
     186                 : // successfully.
     187                 : bool GetAppOutput(const CommandLine& cl, std::string* output);
     188                 : #endif
     189                 : 
     190                 : // Used to filter processes by process ID.
     191                 : class ProcessFilter {
     192                 :  public:
     193                 :   // Returns true to indicate set-inclusion and false otherwise.  This method
     194                 :   // should not have side-effects and should be idempotent.
     195                 :   virtual bool Includes(ProcessId pid, ProcessId parent_pid) const = 0;
     196                 :   virtual ~ProcessFilter() { }
     197                 : };
     198                 : 
     199                 : // Returns the number of processes on the machine that are running from the
     200                 : // given executable name.  If filter is non-null, then only processes selected
     201                 : // by the filter will be counted.
     202                 : int GetProcessCount(const std::wstring& executable_name,
     203                 :                     const ProcessFilter* filter);
     204                 : 
     205                 : // Attempts to kill all the processes on the current machine that were launched
     206                 : // from the given executable name, ending them with the given exit code.  If
     207                 : // filter is non-null, then only processes selected by the filter are killed.
     208                 : // Returns false if all processes were able to be killed off, false if at least
     209                 : // one couldn't be killed.
     210                 : bool KillProcesses(const std::wstring& executable_name, int exit_code,
     211                 :                    const ProcessFilter* filter);
     212                 : 
     213                 : // Attempts to kill the process identified by the given process
     214                 : // entry structure, giving it the specified exit code. If |wait| is true, wait
     215                 : // for the process to be actually terminated before returning.
     216                 : // Returns true if this is successful, false otherwise.
     217                 : bool KillProcess(ProcessHandle process, int exit_code, bool wait);
     218                 : #if defined(OS_WIN)
     219                 : bool KillProcessById(ProcessId process_id, int exit_code, bool wait);
     220                 : #endif
     221                 : 
     222                 : // Get the termination status (exit code) of the process and return true if the
     223                 : // status indicates the process crashed. |child_exited| is set to true iff the
     224                 : // child process has terminated. (|child_exited| may be NULL.)
     225                 : //
     226                 : // On Windows, it is an error to call this if the process hasn't terminated
     227                 : // yet. On POSIX, |child_exited| is set correctly since we detect terminate in
     228                 : // a different manner on POSIX.
     229                 : bool DidProcessCrash(bool* child_exited, ProcessHandle handle);
     230                 : 
     231                 : // Waits for process to exit. In POSIX systems, if the process hasn't been
     232                 : // signaled then puts the exit code in |exit_code|; otherwise it's considered
     233                 : // a failure. On Windows |exit_code| is always filled. Returns true on success,
     234                 : // and closes |handle| in any case.
     235                 : bool WaitForExitCode(ProcessHandle handle, int* exit_code);
     236                 : 
     237                 : // Wait for all the processes based on the named executable to exit.  If filter
     238                 : // is non-null, then only processes selected by the filter are waited on.
     239                 : // Returns after all processes have exited or wait_milliseconds have expired.
     240                 : // Returns true if all the processes exited, false otherwise.
     241                 : bool WaitForProcessesToExit(const std::wstring& executable_name,
     242                 :                             int wait_milliseconds,
     243                 :                             const ProcessFilter* filter);
     244                 : 
     245                 : // Wait for a single process to exit. Return true if it exited cleanly within
     246                 : // the given time limit.
     247                 : bool WaitForSingleProcess(ProcessHandle handle,
     248                 :                           int wait_milliseconds);
     249                 : 
     250                 : // Returns true when |wait_milliseconds| have elapsed and the process
     251                 : // is still running.
     252                 : bool CrashAwareSleep(ProcessHandle handle, int wait_milliseconds);
     253                 : 
     254                 : // Waits a certain amount of time (can be 0) for all the processes with a given
     255                 : // executable name to exit, then kills off any of them that are still around.
     256                 : // If filter is non-null, then only processes selected by the filter are waited
     257                 : // on.  Killed processes are ended with the given exit code.  Returns false if
     258                 : // any processes needed to be killed, true if they all exited cleanly within
     259                 : // the wait_milliseconds delay.
     260                 : bool CleanupProcesses(const std::wstring& executable_name,
     261                 :                       int wait_milliseconds,
     262                 :                       int exit_code,
     263                 :                       const ProcessFilter* filter);
     264                 : 
     265                 : // This class provides a way to iterate through the list of processes
     266                 : // on the current machine that were started from the given executable
     267                 : // name.  To use, create an instance and then call NextProcessEntry()
     268                 : // until it returns false.
     269                 : class NamedProcessIterator {
     270                 :  public:
     271                 :   NamedProcessIterator(const std::wstring& executable_name,
     272                 :                        const ProcessFilter* filter);
     273                 :   ~NamedProcessIterator();
     274                 : 
     275                 :   // If there's another process that matches the given executable name,
     276                 :   // returns a const pointer to the corresponding PROCESSENTRY32.
     277                 :   // If there are no more matching processes, returns NULL.
     278                 :   // The returned pointer will remain valid until NextProcessEntry()
     279                 :   // is called again or this NamedProcessIterator goes out of scope.
     280                 :   const ProcessEntry* NextProcessEntry();
     281                 : 
     282                 :  private:
     283                 :   // Determines whether there's another process (regardless of executable)
     284                 :   // left in the list of all processes.  Returns true and sets entry_ to
     285                 :   // that process's info if there is one, false otherwise.
     286                 :   bool CheckForNextProcess();
     287                 : 
     288                 :   bool IncludeEntry();
     289                 : 
     290                 :   // Initializes a PROCESSENTRY32 data structure so that it's ready for
     291                 :   // use with Process32First/Process32Next.
     292                 :   void InitProcessEntry(ProcessEntry* entry);
     293                 : 
     294                 :   std::wstring executable_name_;
     295                 : 
     296                 : #if defined(OS_WIN)
     297                 :   HANDLE snapshot_;
     298                 :   bool started_iteration_;
     299                 : #elif defined(OS_LINUX)
     300                 :   DIR *procfs_dir_;
     301                 : #elif defined(OS_MACOSX)
     302                 :   std::vector<kinfo_proc> kinfo_procs_;
     303                 :   size_t index_of_kinfo_proc_;
     304                 : #endif
     305                 :   ProcessEntry entry_;
     306                 :   const ProcessFilter* filter_;
     307                 : 
     308                 :   DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator);
     309                 : };
     310                 : 
     311                 : // Working Set (resident) memory usage broken down by
     312                 : // priv (private): These pages (kbytes) cannot be shared with any other process.
     313                 : // shareable:      These pages (kbytes) can be shared with other processes under
     314                 : //                 the right circumstances.
     315                 : // shared :        These pages (kbytes) are currently shared with at least one
     316                 : //                 other process.
     317                 : struct WorkingSetKBytes {
     318                 :   size_t priv;
     319                 :   size_t shareable;
     320                 :   size_t shared;
     321                 : };
     322                 : 
     323                 : // Committed (resident + paged) memory usage broken down by
     324                 : // private: These pages cannot be shared with any other process.
     325                 : // mapped:  These pages are mapped into the view of a section (backed by
     326                 : //          pagefile.sys)
     327                 : // image:   These pages are mapped into the view of an image section (backed by
     328                 : //          file system)
     329                 : struct CommittedKBytes {
     330                 :   size_t priv;
     331                 :   size_t mapped;
     332                 :   size_t image;
     333                 : };
     334                 : 
     335                 : // Free memory (Megabytes marked as free) in the 2G process address space.
     336                 : // total : total amount in megabytes marked as free. Maximum value is 2048.
     337                 : // largest : size of the largest contiguous amount of memory found. It is
     338                 : //   always smaller or equal to FreeMBytes::total.
     339                 : // largest_ptr: starting address of the largest memory block.
     340                 : struct FreeMBytes {
     341                 :   size_t total;
     342                 :   size_t largest;
     343                 :   void* largest_ptr;
     344                 : };
     345                 : 
     346                 : // Provides performance metrics for a specified process (CPU usage, memory and
     347                 : // IO counters). To use it, invoke CreateProcessMetrics() to get an instance
     348                 : // for a specific process, then access the information with the different get
     349                 : // methods.
     350                 : class ProcessMetrics {
     351                 :  public:
     352                 :   // Creates a ProcessMetrics for the specified process.
     353                 :   // The caller owns the returned object.
     354                 :   static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
     355                 : 
     356                 :   ~ProcessMetrics();
     357                 : 
     358                 :   // Returns the current space allocated for the pagefile, in bytes (these pages
     359                 :   // may or may not be in memory).
     360                 :   size_t GetPagefileUsage() const;
     361                 :   // Returns the peak space allocated for the pagefile, in bytes.
     362                 :   size_t GetPeakPagefileUsage() const;
     363                 :   // Returns the current working set size, in bytes.
     364                 :   size_t GetWorkingSetSize() const;
     365                 :   // Returns private usage, in bytes. Private bytes is the amount
     366                 :   // of memory currently allocated to a process that cannot be shared.
     367                 :   // Note: returns 0 on unsupported OSes: prior to XP SP2.
     368                 :   size_t GetPrivateBytes() const;
     369                 :   // Fills a CommittedKBytes with both resident and paged
     370                 :   // memory usage as per definition of CommittedBytes.
     371                 :   void GetCommittedKBytes(CommittedKBytes* usage) const;
     372                 :   // Fills a WorkingSetKBytes containing resident private and shared memory
     373                 :   // usage in bytes, as per definition of WorkingSetBytes.
     374                 :   bool GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const;
     375                 : 
     376                 :   // Computes the current process available memory for allocation.
     377                 :   // It does a linear scan of the address space querying each memory region
     378                 :   // for its free (unallocated) status. It is useful for estimating the memory
     379                 :   // load and fragmentation.
     380                 :   bool CalculateFreeMemory(FreeMBytes* free) const;
     381                 : 
     382                 :   // Returns the CPU usage in percent since the last time this method was
     383                 :   // called. The first time this method is called it returns 0 and will return
     384                 :   // the actual CPU info on subsequent calls.
     385                 :   // Note that on multi-processor machines, the CPU usage value is for all
     386                 :   // CPUs. So if you have 2 CPUs and your process is using all the cycles
     387                 :   // of 1 CPU and not the other CPU, this method returns 50.
     388                 :   int GetCPUUsage();
     389                 : 
     390                 :   // Retrieves accounting information for all I/O operations performed by the
     391                 :   // process.
     392                 :   // If IO information is retrieved successfully, the function returns true
     393                 :   // and fills in the IO_COUNTERS passed in. The function returns false
     394                 :   // otherwise.
     395                 :   bool GetIOCounters(IoCounters* io_counters) const;
     396                 : 
     397                 :  private:
     398                 :   explicit ProcessMetrics(ProcessHandle process);
     399                 : 
     400                 :   ProcessHandle process_;
     401                 : 
     402                 :   int processor_count_;
     403                 : 
     404                 :   // Used to store the previous times so we can compute the CPU usage.
     405                 :   int64 last_time_;
     406                 :   int64 last_system_time_;
     407                 : 
     408                 :   DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics);
     409                 : };
     410                 : 
     411                 : // Enables low fragmentation heap (LFH) for every heaps of this process. This
     412                 : // won't have any effect on heaps created after this function call. It will not
     413                 : // modify data allocated in the heaps before calling this function. So it is
     414                 : // better to call this function early in initialization and again before
     415                 : // entering the main loop.
     416                 : // Note: Returns true on Windows 2000 without doing anything.
     417                 : bool EnableLowFragmentationHeap();
     418                 : 
     419                 : // Enable 'terminate on heap corruption' flag. Helps protect against heap
     420                 : // overflow. Has no effect if the OS doesn't provide the necessary facility.
     421                 : void EnableTerminationOnHeapCorruption();
     422                 : 
     423                 : // If supported on the platform, and the user has sufficent rights, increase
     424                 : // the current process's scheduling priority to a high priority.
     425                 : void RaiseProcessToHighPriority();
     426                 : 
     427                 : }  // namespace base
     428                 : 
     429                 : #endif  // BASE_PROCESS_UTIL_H_

Generated by: LCOV version 1.7