process_util.h revision bc7e0823f37810f402bf7f115ee7ccd673f5ac34
1// Copyright (c) 2010 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#pragma once
11
12#include "base/basictypes.h"
13
14#if defined(OS_WIN)
15#include <windows.h>
16#include <tlhelp32.h>
17#elif defined(OS_MACOSX)
18// kinfo_proc is defined in <sys/sysctl.h>, but this forward declaration
19// is sufficient for the vector<kinfo_proc> below.
20struct kinfo_proc;
21// malloc_zone_t is defined in <malloc/malloc.h>, but this forward declaration
22// is sufficient for GetPurgeableZone() below.
23typedef struct _malloc_zone_t malloc_zone_t;
24#include <mach/mach.h>
25#elif defined(OS_POSIX)
26#include <dirent.h>
27#include <limits.h>
28#include <sys/types.h>
29#endif
30
31#include <list>
32#include <string>
33#include <utility>
34#include <vector>
35
36#include "base/file_descriptor_shuffle.h"
37#include "base/process.h"
38
39#ifndef NAME_MAX  // Solaris and some BSDs have no NAME_MAX
40#ifdef MAXNAMLEN
41#define NAME_MAX MAXNAMLEN
42#else
43#define NAME_MAX 256
44#endif
45#endif
46
47class CommandLine;
48class FilePath;
49
50namespace base {
51
52#if defined(OS_WIN)
53
54struct ProcessEntry : public PROCESSENTRY32 {
55  ProcessId pid() const { return th32ProcessID; }
56  ProcessId parent_pid() const { return th32ParentProcessID; }
57  const wchar_t* exe_file() const { return szExeFile; }
58};
59
60struct IoCounters : public IO_COUNTERS {
61};
62
63#elif defined(OS_POSIX)
64
65struct ProcessEntry {
66  ProcessId pid_;
67  ProcessId ppid_;
68  ProcessId gid_;
69  std::string exe_file_;
70
71  ProcessId pid() const { return pid_; }
72  ProcessId parent_pid() const { return ppid_; }
73  const char* exe_file() const { return exe_file_.c_str(); }
74};
75
76struct IoCounters {
77  uint64_t ReadOperationCount;
78  uint64_t WriteOperationCount;
79  uint64_t OtherOperationCount;
80  uint64_t ReadTransferCount;
81  uint64_t WriteTransferCount;
82  uint64_t OtherTransferCount;
83};
84
85#endif  // defined(OS_POSIX)
86
87// A minimalistic but hopefully cross-platform set of exit codes.
88// Do not change the enumeration values or you will break third-party
89// installers.
90enum {
91  PROCESS_END_NORMAL_TERMINATION = 0,
92  PROCESS_END_KILLED_BY_USER     = 1,
93  PROCESS_END_PROCESS_WAS_HUNG   = 2
94};
95
96// Returns the id of the current process.
97ProcessId GetCurrentProcId();
98
99// Returns the ProcessHandle of the current process.
100ProcessHandle GetCurrentProcessHandle();
101
102// Converts a PID to a process handle. This handle must be closed by
103// CloseProcessHandle when you are done with it. Returns true on success.
104bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle);
105
106// Converts a PID to a process handle. On Windows the handle is opened
107// with more access rights and must only be used by trusted code.
108// You have to close returned handle using CloseProcessHandle. Returns true
109// on success.
110bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle);
111
112// Closes the process handle opened by OpenProcessHandle.
113void CloseProcessHandle(ProcessHandle process);
114
115// Returns the unique ID for the specified process. This is functionally the
116// same as Windows' GetProcessId(), but works on versions of Windows before
117// Win XP SP1 as well.
118ProcessId GetProcId(ProcessHandle process);
119
120#if defined(OS_LINUX)
121// Returns the ID for the parent of the given process.
122ProcessId GetParentProcessId(ProcessHandle process);
123
124// Returns the path to the executable of the given process.
125FilePath GetProcessExecutablePath(ProcessHandle process);
126
127// Parse the data found in /proc/<pid>/stat and return the sum of the
128// CPU-related ticks.  Returns -1 on parse error.
129// Exposed for testing.
130int ParseProcStatCPU(const std::string& input);
131
132static const char kAdjustOOMScoreSwitch[] = "--adjust-oom-score";
133
134// This adjusts /proc/process/oom_adj so the Linux OOM killer will prefer
135// certain process types over others. The range for the adjustment is
136// [-17,15], with [0,15] being user accessible.
137bool AdjustOOMScore(ProcessId process, int score);
138#endif
139
140#if defined(OS_POSIX)
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.
144void CloseSuperfluousFds(const InjectiveMultimap& saved_map);
145#endif
146
147#if defined(OS_WIN)
148
149enum IntegrityLevel {
150  INTEGRITY_UNKNOWN,
151  LOW_INTEGRITY,
152  MEDIUM_INTEGRITY,
153  HIGH_INTEGRITY,
154};
155// Determine the integrity level of the specified process. Returns false
156// if the system does not support integrity levels (pre-Vista) or in the case
157// of an underlying system failure.
158bool GetProcessIntegrityLevel(ProcessHandle process, IntegrityLevel *level);
159
160// Runs the given application name with the given command line. Normally, the
161// first command line argument should be the path to the process, and don't
162// forget to quote it.
163//
164// If wait is true, it will block and wait for the other process to finish,
165// otherwise, it will just continue asynchronously.
166//
167// Example (including literal quotes)
168//  cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
169//
170// If process_handle is non-NULL, the process handle of the launched app will be
171// stored there on a successful launch.
172// NOTE: In this case, the caller is responsible for closing the handle so
173//       that it doesn't leak!
174bool LaunchApp(const std::wstring& cmdline,
175               bool wait, bool start_hidden, ProcessHandle* process_handle);
176
177// Same as LaunchApp, except allows the new process to inherit handles of the
178// parent process.
179bool LaunchAppWithHandleInheritance(const std::wstring& cmdline,
180                                    bool wait,
181                                    bool start_hidden,
182                                    ProcessHandle* process_handle);
183
184// Runs the given application name with the given command line as if the user
185// represented by |token| had launched it. The caveats about |cmdline| and
186// |process_handle| explained for LaunchApp above apply as well.
187//
188// Whether the application is visible on the interactive desktop depends on
189// the token belonging to an interactive logon session.
190//
191// To avoid hard to diagnose problems, this function internally loads the
192// environment variables associated with the user and if this operation fails
193// the entire call fails as well.
194bool LaunchAppAsUser(UserTokenHandle token, const std::wstring& cmdline,
195                     bool start_hidden, ProcessHandle* process_handle);
196
197// Has the same behavior as LaunchAppAsUser, but offers the boolean option to
198// use an empty string for the desktop name and a boolean for allowing the
199// child process to inherit handles from its parent.
200bool LaunchAppAsUser(UserTokenHandle token, const std::wstring& cmdline,
201                     bool start_hidden, ProcessHandle* process_handle,
202                     bool empty_desktop_name, bool inherit_handles);
203
204
205#elif defined(OS_POSIX)
206// Runs the application specified in argv[0] with the command line argv.
207// Before launching all FDs open in the parent process will be marked as
208// close-on-exec.  |fds_to_remap| defines a mapping of src fd->dest fd to
209// propagate FDs into the child process.
210//
211// As above, if wait is true, execute synchronously. The pid will be stored
212// in process_handle if that pointer is non-null.
213//
214// Note that the first argument in argv must point to the executable filename.
215// If the filename is not fully specified, PATH will be searched.
216typedef std::vector<std::pair<int, int> > file_handle_mapping_vector;
217bool LaunchApp(const std::vector<std::string>& argv,
218               const file_handle_mapping_vector& fds_to_remap,
219               bool wait, ProcessHandle* process_handle);
220
221// Similar to the above, but also (un)set environment variables in child process
222// through |environ|.
223typedef std::vector<std::pair<std::string, std::string> > environment_vector;
224bool LaunchApp(const std::vector<std::string>& argv,
225               const environment_vector& environ,
226               const file_handle_mapping_vector& fds_to_remap,
227               bool wait, ProcessHandle* process_handle);
228
229// Similar to the above two methods, but starts the child process in a process
230// group of its own, instead of allowing it to inherit the parent's process
231// group. The pgid of the child process will be the same as its pid.
232bool LaunchAppInNewProcessGroup(const std::vector<std::string>& argv,
233                                const environment_vector& environ,
234                                const file_handle_mapping_vector& fds_to_remap,
235                                bool wait, ProcessHandle* process_handle);
236
237// AlterEnvironment returns a modified environment vector, constructed from the
238// given environment and the list of changes given in |changes|. Each key in
239// the environment is matched against the first element of the pairs. In the
240// event of a match, the value is replaced by the second of the pair, unless
241// the second is empty, in which case the key-value is removed.
242//
243// The returned array is allocated using new[] and must be freed by the caller.
244char** AlterEnvironment(const environment_vector& changes,
245                        const char* const* const env);
246#endif  // defined(OS_POSIX)
247
248// Executes the application specified by cl. This function delegates to one
249// of the above two platform-specific functions.
250bool LaunchApp(const CommandLine& cl,
251               bool wait, bool start_hidden, ProcessHandle* process_handle);
252
253// Executes the application specified by |cl| and wait for it to exit. Stores
254// the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true
255// on success (application launched and exited cleanly, with exit code
256// indicating success).
257bool GetAppOutput(const CommandLine& cl, std::string* output);
258
259#if defined(OS_POSIX)
260// A restricted version of |GetAppOutput()| which (a) clears the environment,
261// and (b) stores at most |max_output| bytes; also, it doesn't search the path
262// for the command.
263bool GetAppOutputRestricted(const CommandLine& cl,
264                            std::string* output, size_t max_output);
265#endif
266
267// Used to filter processes by process ID.
268class ProcessFilter {
269 public:
270  // Returns true to indicate set-inclusion and false otherwise.  This method
271  // should not have side-effects and should be idempotent.
272  virtual bool Includes(const ProcessEntry& entry) const = 0;
273
274 protected:
275  virtual ~ProcessFilter() {}
276};
277
278// Returns the number of processes on the machine that are running from the
279// given executable name.  If filter is non-null, then only processes selected
280// by the filter will be counted.
281int GetProcessCount(const std::wstring& executable_name,
282                    const ProcessFilter* filter);
283
284// Attempts to kill all the processes on the current machine that were launched
285// from the given executable name, ending them with the given exit code.  If
286// filter is non-null, then only processes selected by the filter are killed.
287// Returns true if all processes were able to be killed off, false if at least
288// one couldn't be killed.
289bool KillProcesses(const std::wstring& executable_name, int exit_code,
290                   const ProcessFilter* filter);
291
292// Attempts to kill the process identified by the given process
293// entry structure, giving it the specified exit code. If |wait| is true, wait
294// for the process to be actually terminated before returning.
295// Returns true if this is successful, false otherwise.
296bool KillProcess(ProcessHandle process, int exit_code, bool wait);
297
298#if defined(OS_POSIX)
299// Attempts to kill the process group identified by |process_group_id|. Returns
300// true on success.
301bool KillProcessGroup(ProcessHandle process_group_id);
302#endif
303
304#if defined(OS_WIN)
305bool KillProcessById(ProcessId process_id, int exit_code, bool wait);
306#endif
307
308// Get the termination status (exit code) of the process and return true if the
309// status indicates the process crashed. |child_exited| is set to true iff the
310// child process has terminated. (|child_exited| may be NULL.)
311bool DidProcessCrash(bool* child_exited, ProcessHandle handle);
312
313// Waits for process to exit. In POSIX systems, if the process hasn't been
314// signaled then puts the exit code in |exit_code|; otherwise it's considered
315// a failure. On Windows |exit_code| is always filled. Returns true on success,
316// and closes |handle| in any case.
317bool WaitForExitCode(ProcessHandle handle, int* exit_code);
318
319// Waits for process to exit. If it did exit within |timeout_milliseconds|,
320// then puts the exit code in |exit_code|, closes |handle|, and returns true.
321// In POSIX systems, if the process has been signaled then |exit_code| is set
322// to -1. Returns false on failure (the caller is then responsible for closing
323// |handle|).
324bool WaitForExitCodeWithTimeout(ProcessHandle handle, int* exit_code,
325                                int64 timeout_milliseconds);
326
327// Wait for all the processes based on the named executable to exit.  If filter
328// is non-null, then only processes selected by the filter are waited on.
329// Returns after all processes have exited or wait_milliseconds have expired.
330// Returns true if all the processes exited, false otherwise.
331bool WaitForProcessesToExit(const std::wstring& executable_name,
332                            int64 wait_milliseconds,
333                            const ProcessFilter* filter);
334
335// Wait for a single process to exit. Return true if it exited cleanly within
336// the given time limit.
337bool WaitForSingleProcess(ProcessHandle handle,
338                          int64 wait_milliseconds);
339
340// Returns true when |wait_milliseconds| have elapsed and the process
341// is still running.
342bool CrashAwareSleep(ProcessHandle handle, int64 wait_milliseconds);
343
344// Waits a certain amount of time (can be 0) for all the processes with a given
345// executable name to exit, then kills off any of them that are still around.
346// If filter is non-null, then only processes selected by the filter are waited
347// on.  Killed processes are ended with the given exit code.  Returns false if
348// any processes needed to be killed, true if they all exited cleanly within
349// the wait_milliseconds delay.
350bool CleanupProcesses(const std::wstring& executable_name,
351                      int64 wait_milliseconds,
352                      int exit_code,
353                      const ProcessFilter* filter);
354
355// This class provides a way to iterate through a list of processes on the
356// current machine with a specified filter.
357// To use, create an instance and then call NextProcessEntry() until it returns
358// false.
359class ProcessIterator {
360 public:
361  typedef std::list<ProcessEntry> ProcessEntries;
362
363  explicit ProcessIterator(const ProcessFilter* filter);
364  virtual ~ProcessIterator();
365
366  // If there's another process that matches the given executable name,
367  // returns a const pointer to the corresponding PROCESSENTRY32.
368  // If there are no more matching processes, returns NULL.
369  // The returned pointer will remain valid until NextProcessEntry()
370  // is called again or this NamedProcessIterator goes out of scope.
371  const ProcessEntry* NextProcessEntry();
372
373  // Takes a snapshot of all the ProcessEntry found.
374  ProcessEntries Snapshot();
375
376 protected:
377  virtual bool IncludeEntry();
378  const ProcessEntry& entry() { return entry_; }
379
380 private:
381  // Determines whether there's another process (regardless of executable)
382  // left in the list of all processes.  Returns true and sets entry_ to
383  // that process's info if there is one, false otherwise.
384  bool CheckForNextProcess();
385
386  // Initializes a PROCESSENTRY32 data structure so that it's ready for
387  // use with Process32First/Process32Next.
388  void InitProcessEntry(ProcessEntry* entry);
389
390#if defined(OS_WIN)
391  HANDLE snapshot_;
392  bool started_iteration_;
393#elif defined(OS_MACOSX)
394  std::vector<kinfo_proc> kinfo_procs_;
395  size_t index_of_kinfo_proc_;
396#elif defined(OS_POSIX)
397  DIR *procfs_dir_;
398#endif
399  ProcessEntry entry_;
400  const ProcessFilter* filter_;
401
402  DISALLOW_COPY_AND_ASSIGN(ProcessIterator);
403};
404
405// This class provides a way to iterate through the list of processes
406// on the current machine that were started from the given executable
407// name.  To use, create an instance and then call NextProcessEntry()
408// until it returns false.
409class NamedProcessIterator : public ProcessIterator {
410 public:
411  NamedProcessIterator(const std::wstring& executable_name,
412                       const ProcessFilter* filter);
413  virtual ~NamedProcessIterator();
414
415 protected:
416  virtual bool IncludeEntry();
417
418 private:
419  std::wstring executable_name_;
420
421  DISALLOW_COPY_AND_ASSIGN(NamedProcessIterator);
422};
423
424// Working Set (resident) memory usage broken down by
425//
426// On Windows:
427// priv (private): These pages (kbytes) cannot be shared with any other process.
428// shareable:      These pages (kbytes) can be shared with other processes under
429//                 the right circumstances.
430// shared :        These pages (kbytes) are currently shared with at least one
431//                 other process.
432//
433// On Linux:
434// priv:           Pages mapped only by this process
435// shared:         PSS or 0 if the kernel doesn't support this
436// shareable:      0
437//
438// On OS X: TODO(thakis): Revise.
439// priv:           Memory.
440// shared:         0
441// shareable:      0
442struct WorkingSetKBytes {
443  WorkingSetKBytes() : priv(0), shareable(0), shared(0) {}
444  size_t priv;
445  size_t shareable;
446  size_t shared;
447};
448
449// Committed (resident + paged) memory usage broken down by
450// private: These pages cannot be shared with any other process.
451// mapped:  These pages are mapped into the view of a section (backed by
452//          pagefile.sys)
453// image:   These pages are mapped into the view of an image section (backed by
454//          file system)
455struct CommittedKBytes {
456  CommittedKBytes() : priv(0), mapped(0), image(0) {}
457  size_t priv;
458  size_t mapped;
459  size_t image;
460};
461
462// Free memory (Megabytes marked as free) in the 2G process address space.
463// total : total amount in megabytes marked as free. Maximum value is 2048.
464// largest : size of the largest contiguous amount of memory found. It is
465//   always smaller or equal to FreeMBytes::total.
466// largest_ptr: starting address of the largest memory block.
467struct FreeMBytes {
468  size_t total;
469  size_t largest;
470  void* largest_ptr;
471};
472
473// Convert a POSIX timeval to microseconds.
474int64 TimeValToMicroseconds(const struct timeval& tv);
475
476// Provides performance metrics for a specified process (CPU usage, memory and
477// IO counters). To use it, invoke CreateProcessMetrics() to get an instance
478// for a specific process, then access the information with the different get
479// methods.
480class ProcessMetrics {
481 public:
482  // Creates a ProcessMetrics for the specified process.
483  // The caller owns the returned object.
484#if !defined(OS_MACOSX)
485  static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
486#else
487  class PortProvider {
488   public:
489    // Should return the mach task for |process| if possible, or else
490    // |MACH_PORT_NULL|. Only processes that this returns tasks for will have
491    // metrics on OS X (except for the current process, which always gets
492    // metrics).
493    virtual mach_port_t TaskForPid(ProcessHandle process) const = 0;
494  };
495
496  // The port provider needs to outlive the ProcessMetrics object returned by
497  // this function. If NULL is passed as provider, the returned object
498  // only returns valid metrics if |process| is the current process.
499  static ProcessMetrics* CreateProcessMetrics(ProcessHandle process,
500                                              PortProvider* port_provider);
501#endif  // !defined(OS_MACOSX)
502
503  ~ProcessMetrics();
504
505  // Returns the current space allocated for the pagefile, in bytes (these pages
506  // may or may not be in memory).  On Linux, this returns the total virtual
507  // memory size.
508  size_t GetPagefileUsage() const;
509  // Returns the peak space allocated for the pagefile, in bytes.
510  size_t GetPeakPagefileUsage() const;
511  // Returns the current working set size, in bytes.  On Linux, this returns
512  // the resident set size.
513  size_t GetWorkingSetSize() const;
514  // Returns the peak working set size, in bytes.
515  size_t GetPeakWorkingSetSize() const;
516  // Returns private and sharedusage, in bytes. Private bytes is the amount of
517  // memory currently allocated to a process that cannot be shared. Returns
518  // false on platform specific error conditions.  Note: |private_bytes|
519  // returns 0 on unsupported OSes: prior to XP SP2.
520  bool GetMemoryBytes(size_t* private_bytes,
521                      size_t* shared_bytes);
522  // Fills a CommittedKBytes with both resident and paged
523  // memory usage as per definition of CommittedBytes.
524  void GetCommittedKBytes(CommittedKBytes* usage) const;
525  // Fills a WorkingSetKBytes containing resident private and shared memory
526  // usage in bytes, as per definition of WorkingSetBytes.
527  bool GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const;
528
529  // Computes the current process available memory for allocation.
530  // It does a linear scan of the address space querying each memory region
531  // for its free (unallocated) status. It is useful for estimating the memory
532  // load and fragmentation.
533  bool CalculateFreeMemory(FreeMBytes* free) const;
534
535  // Returns the CPU usage in percent since the last time this method was
536  // called. The first time this method is called it returns 0 and will return
537  // the actual CPU info on subsequent calls.
538  // On Windows, the CPU usage value is for all CPUs. So if you have 2 CPUs and
539  // your process is using all the cycles of 1 CPU and not the other CPU, this
540  // method returns 50.
541  double GetCPUUsage();
542
543  // Retrieves accounting information for all I/O operations performed by the
544  // process.
545  // If IO information is retrieved successfully, the function returns true
546  // and fills in the IO_COUNTERS passed in. The function returns false
547  // otherwise.
548  bool GetIOCounters(IoCounters* io_counters) const;
549
550 private:
551#if !defined(OS_MACOSX)
552  explicit ProcessMetrics(ProcessHandle process);
553#else
554  ProcessMetrics(ProcessHandle process, PortProvider* port_provider);
555#endif  // !defined(OS_MACOSX)
556
557  ProcessHandle process_;
558
559  int processor_count_;
560
561  // Used to store the previous times and CPU usage counts so we can
562  // compute the CPU usage between calls.
563  int64 last_time_;
564  int64 last_system_time_;
565
566#if defined(OS_MACOSX)
567  // Queries the port provider if it's set.
568  mach_port_t TaskForPid(ProcessHandle process) const;
569
570  PortProvider* port_provider_;
571#elif defined(OS_POSIX)
572  // Jiffie count at the last_time_ we updated.
573  int last_cpu_;
574#endif  // defined(OS_MACOSX)
575
576  DISALLOW_COPY_AND_ASSIGN(ProcessMetrics);
577};
578
579// Returns the memory commited by the system in KBytes.
580// Returns 0 if it can't compute the commit charge.
581size_t GetSystemCommitCharge();
582
583// Enables low fragmentation heap (LFH) for every heaps of this process. This
584// won't have any effect on heaps created after this function call. It will not
585// modify data allocated in the heaps before calling this function. So it is
586// better to call this function early in initialization and again before
587// entering the main loop.
588// Note: Returns true on Windows 2000 without doing anything.
589bool EnableLowFragmentationHeap();
590
591// Enables 'terminate on heap corruption' flag. Helps protect against heap
592// overflow. Has no effect if the OS doesn't provide the necessary facility.
593void EnableTerminationOnHeapCorruption();
594
595#if !defined(OS_WIN)
596// Turns on process termination if memory runs out. This is handled on Windows
597// inside RegisterInvalidParamHandler().
598void EnableTerminationOnOutOfMemory();
599#if defined(OS_MACOSX)
600// Exposed for testing.
601malloc_zone_t* GetPurgeableZone();
602#endif
603#endif
604
605#if defined(UNIT_TEST)
606// Enables stack dump to console output on exception and signals.
607// When enabled, the process will quit immediately. This is meant to be used in
608// unit_tests only!
609bool EnableInProcessStackDumping();
610#endif  // defined(UNIT_TEST)
611
612// If supported on the platform, and the user has sufficent rights, increase
613// the current process's scheduling priority to a high priority.
614void RaiseProcessToHighPriority();
615
616#if defined(OS_MACOSX)
617// Restore the default exception handler, setting it to Apple Crash Reporter
618// (ReportCrash).  When forking and execing a new process, the child will
619// inherit the parent's exception ports, which may be set to the Breakpad
620// instance running inside the parent.  The parent's Breakpad instance should
621// not handle the child's exceptions.  Calling RestoreDefaultExceptionHandler
622// in the child after forking will restore the standard exception handler.
623// See http://crbug.com/20371/ for more details.
624void RestoreDefaultExceptionHandler();
625#endif  // defined(OS_MACOSX)
626
627}  // namespace base
628
629#endif  // BASE_PROCESS_UTIL_H_
630