[go: nahoru, domu]

blob: c921d7a2d745dbaaea6a097c778fa0e193790c3a [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 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.
initial.commitd7cae122008-07-26 21:49:384
5// This file/namespace contains utility functions for enumerating, ending and
6// computing statistics of processes.
7
deanm@google.comdb717282008-08-27 13:48:038#ifndef BASE_PROCESS_UTIL_H_
9#define BASE_PROCESS_UTIL_H_
initial.commitd7cae122008-07-26 21:49:3810
paulg@google.com61659062008-08-06 01:04:1811#include "base/basictypes.h"
12
dkegel@google.comab0e2222008-10-31 20:19:4313#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:3814#include <windows.h>
15#include <tlhelp32.h>
dkegel@google.comab0e2222008-10-31 20:19:4316#elif defined(OS_LINUX)
17#include <dirent.h>
18#include <limits.h>
19#include <sys/types.h>
paulg@google.com61659062008-08-06 01:04:1820#endif
initial.commitd7cae122008-07-26 21:49:3821
paulg@google.com61659062008-08-06 01:04:1822#include <string>
mark@chromium.org962dd312009-02-05 21:44:1323#include <vector>
paulg@google.com61659062008-08-06 01:04:1824
estade@chromium.orgfb7f9be2008-10-22 01:15:4725#include "base/command_line.h"
initial.commitd7cae122008-07-26 21:49:3826#include "base/process.h"
27
paulg@google.com61659062008-08-06 01:04:1828#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:3829typedef PROCESSENTRY32 ProcessEntry;
30typedef IO_COUNTERS IoCounters;
paulg@google.com61659062008-08-06 01:04:1831#elif defined(OS_POSIX)
mark@chromium.org962dd312009-02-05 21:44:1332// TODO(port): we should not rely on a Win32 structure.
dkegel@google.comab0e2222008-10-31 20:19:4333struct ProcessEntry {
34 int pid;
35 int ppid;
mark@chromium.org962dd312009-02-05 21:44:1336 char szExeFile[NAME_MAX + 1];
dkegel@google.comab0e2222008-10-31 20:19:4337};
38
evanm@google.com0b100bc82008-10-14 20:49:1639struct IoCounters {
40 unsigned long long ReadOperationCount;
41 unsigned long long WriteOperationCount;
42 unsigned long long OtherOperationCount;
43 unsigned long long ReadTransferCount;
44 unsigned long long WriteTransferCount;
45 unsigned long long OtherTransferCount;
46};
mark@chromium.org962dd312009-02-05 21:44:1347#endif
48
49#if defined(OS_MACOSX)
50struct kinfo_proc;
initial.commitd7cae122008-07-26 21:49:3851#endif
52
brettw@google.com176aa482008-11-14 03:25:1553namespace base {
initial.commitd7cae122008-07-26 21:49:3854
cpu@google.comeef576f2008-11-03 23:28:0655// A minimalistic but hopefully cross-platform set of exit codes.
56// Do not change the enumeration values or you will break third-party
57// installers.
58enum {
59 PROCESS_END_NORMAL_TERMINATON = 0,
60 PROCESS_END_KILLED_BY_USER = 1,
61 PROCESS_END_PROCESS_WAS_HUNG = 2
62};
63
initial.commitd7cae122008-07-26 21:49:3864// Returns the id of the current process.
65int GetCurrentProcId();
66
erikkay@google.com113ab132008-09-18 20:42:5567// Returns the ProcessHandle of the current process.
68ProcessHandle GetCurrentProcessHandle();
brettw@google.com5986ed22009-02-06 00:19:1769
70// Converts a PID to a process handle. This handle must be closed by
71// CloseProcessHandle when you are done with it.
72ProcessHandle OpenProcessHandle(int pid);
73
74// Closes the process handle opened by OpenProcessHandle.
75void CloseProcessHandle(ProcessHandle process);
erikkay@google.com113ab132008-09-18 20:42:5576
cpu@google.comeef576f2008-11-03 23:28:0677// Returns the unique ID for the specified process. This is functionally the
initial.commitd7cae122008-07-26 21:49:3878// same as Windows' GetProcessId(), but works on versions of Windows before
79// Win XP SP1 as well.
80int GetProcId(ProcessHandle process);
81
jeremy@chromium.orgfa3097a6a52008-12-17 22:41:5082#if defined(OS_POSIX)
jeremy@chromium.org05d4b0a2009-01-29 17:51:5183// Sets all file descriptors to close on exec except for stdin, stdout
84// and stderr.
85void SetAllFDsToCloseOnExec();
jeremy@chromium.orgfa3097a6a52008-12-17 22:41:5086#endif
87
estade@chromium.orgfb7f9be2008-10-22 01:15:4788#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:3889// Runs the given application name with the given command line. Normally, the
90// first command line argument should be the path to the process, and don't
91// forget to quote it.
92//
93// If wait is true, it will block and wait for the other process to finish,
94// otherwise, it will just continue asynchronously.
95//
96// Example (including literal quotes)
97// cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
98//
99// If process_handle is non-NULL, the process handle of the launched app will be
100// stored there on a successful launch.
101// NOTE: In this case, the caller is responsible for closing the handle so
102// that it doesn't leak!
103bool LaunchApp(const std::wstring& cmdline,
estade@chromium.orgfb7f9be2008-10-22 01:15:47104 bool wait, bool start_hidden, ProcessHandle* process_handle);
105#elif defined(OS_POSIX)
106// Runs the application specified in argv[0] with the command line argv.
jeremy@chromium.orgfa3097a6a52008-12-17 22:41:50107// Before launching all FDs open in the parent process will be marked as
108// close-on-exec. |fds_to_remap| defines a mapping of src fd->dest fd to
109// propagate FDs into the child process.
estade@chromium.orgfb7f9be2008-10-22 01:15:47110//
111// As above, if wait is true, execute synchronously. The pid will be stored
112// in process_handle if that pointer is non-null.
113//
114// Note that the first argument in argv must point to the filename,
115// and must be fully specified.
jeremy@chromium.orgfa3097a6a52008-12-17 22:41:50116typedef std::vector<std::pair<int, int> > file_handle_mapping_vector;
estade@chromium.orgfb7f9be2008-10-22 01:15:47117bool LaunchApp(const std::vector<std::string>& argv,
jeremy@chromium.orgfa3097a6a52008-12-17 22:41:50118 const file_handle_mapping_vector& fds_to_remap,
estade@chromium.orgfb7f9be2008-10-22 01:15:47119 bool wait, ProcessHandle* process_handle);
120#endif
121
122// Execute the application specified by cl. This function delegates to one
123// of the above two platform-specific functions.
124bool LaunchApp(const CommandLine& cl,
initial.commitd7cae122008-07-26 21:49:38125 bool wait, bool start_hidden, ProcessHandle* process_handle);
126
127// Used to filter processes by process ID.
128class ProcessFilter {
129 public:
130 // Returns true to indicate set-inclusion and false otherwise. This method
131 // should not have side-effects and should be idempotent.
132 virtual bool Includes(uint32 pid, uint32 parent_pid) const = 0;
avi@google.comdd950aa2008-08-12 21:24:39133 virtual ~ProcessFilter() { }
initial.commitd7cae122008-07-26 21:49:38134};
135
136// Returns the number of processes on the machine that are running from the
137// given executable name. If filter is non-null, then only processes selected
138// by the filter will be counted.
139int GetProcessCount(const std::wstring& executable_name,
140 const ProcessFilter* filter);
141
142// Attempts to kill all the processes on the current machine that were launched
143// from the given executable name, ending them with the given exit code. If
144// filter is non-null, then only processes selected by the filter are killed.
145// Returns false if all processes were able to be killed off, false if at least
146// one couldn't be killed.
147bool KillProcesses(const std::wstring& executable_name, int exit_code,
148 const ProcessFilter* filter);
149
150// Attempts to kill the process identified by the given process
151// entry structure, giving it the specified exit code. If |wait| is true, wait
152// for the process to be actually terminated before returning.
153// Returns true if this is successful, false otherwise.
154bool KillProcess(int process_id, int exit_code, bool wait);
agl@chromium.orgdfe14862009-01-22 01:23:11155#if defined(OS_WIN)
156bool KillProcess(HANDLE process, int exit_code, bool wait);
157#endif
initial.commitd7cae122008-07-26 21:49:38158
159// Get the termination status (exit code) of the process and return true if the
160// status indicates the process crashed. It is an error to call this if the
161// process hasn't terminated yet.
162bool DidProcessCrash(ProcessHandle handle);
163
phajdan.jr@chromium.orgc7856632009-01-13 17:38:49164// Waits for process to exit. In POSIX systems, if the process hasn't been
165// signaled then puts the exit code in |exit_code|; otherwise it's considered
166// a failure. On Windows |exit_code| is always filled. Returns true on success,
167// and closes |handle| in any case.
168bool WaitForExitCode(ProcessHandle handle, int* exit_code);
169
initial.commitd7cae122008-07-26 21:49:38170// Wait for all the processes based on the named executable to exit. If filter
171// is non-null, then only processes selected by the filter are waited on.
172// Returns after all processes have exited or wait_milliseconds have expired.
173// Returns true if all the processes exited, false otherwise.
174bool WaitForProcessesToExit(const std::wstring& executable_name,
175 int wait_milliseconds,
176 const ProcessFilter* filter);
177
estade@chromium.orgfb7f9be2008-10-22 01:15:47178// Wait for a single process to exit. Return true if it exited cleanly within
179// the given time limit.
180bool WaitForSingleProcess(ProcessHandle handle,
181 int wait_milliseconds);
182
initial.commitd7cae122008-07-26 21:49:38183// Waits a certain amount of time (can be 0) for all the processes with a given
184// executable name to exit, then kills off any of them that are still around.
185// If filter is non-null, then only processes selected by the filter are waited
186// on. Killed processes are ended with the given exit code. Returns false if
187// any processes needed to be killed, true if they all exited cleanly within
188// the wait_milliseconds delay.
189bool CleanupProcesses(const std::wstring& executable_name,
190 int wait_milliseconds,
191 int exit_code,
192 const ProcessFilter* filter);
193
194// This class provides a way to iterate through the list of processes
195// on the current machine that were started from the given executable
196// name. To use, create an instance and then call NextProcessEntry()
197// until it returns false.
198class NamedProcessIterator {
199 public:
200 NamedProcessIterator(const std::wstring& executable_name,
201 const ProcessFilter* filter);
202 ~NamedProcessIterator();
203
204 // If there's another process that matches the given executable name,
205 // returns a const pointer to the corresponding PROCESSENTRY32.
206 // If there are no more matching processes, returns NULL.
207 // The returned pointer will remain valid until NextProcessEntry()
208 // is called again or this NamedProcessIterator goes out of scope.
209 const ProcessEntry* NextProcessEntry();
210
211 private:
212 // Determines whether there's another process (regardless of executable)
213 // left in the list of all processes. Returns true and sets entry_ to
214 // that process's info if there is one, false otherwise.
215 bool CheckForNextProcess();
216
217 bool IncludeEntry();
218
219 // Initializes a PROCESSENTRY32 data structure so that it's ready for
220 // use with Process32First/Process32Next.
221 void InitProcessEntry(ProcessEntry* entry);
222
223 std::wstring executable_name_;
dkegel@google.comab0e2222008-10-31 20:19:43224
225#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:38226 HANDLE snapshot_;
initial.commitd7cae122008-07-26 21:49:38227 bool started_iteration_;
dkegel@google.comab0e2222008-10-31 20:19:43228#elif defined(OS_LINUX)
229 DIR *procfs_dir_;
230#elif defined(OS_MACOSX)
mark@chromium.org962dd312009-02-05 21:44:13231 std::vector<kinfo_proc> kinfo_procs_;
232 size_t index_of_kinfo_proc_;
dkegel@google.comab0e2222008-10-31 20:19:43233#endif
initial.commitd7cae122008-07-26 21:49:38234 ProcessEntry entry_;
235 const ProcessFilter* filter_;
236
237 DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator);
238};
239
240// Working Set (resident) memory usage broken down by
241// priv (private): These pages (kbytes) cannot be shared with any other process.
242// shareable: These pages (kbytes) can be shared with other processes under
243// the right circumstances.
244// shared : These pages (kbytes) are currently shared with at least one
245// other process.
246struct WorkingSetKBytes {
247 size_t priv;
248 size_t shareable;
249 size_t shared;
250};
251
252// Committed (resident + paged) memory usage broken down by
253// private: These pages cannot be shared with any other process.
254// mapped: These pages are mapped into the view of a section (backed by
255// pagefile.sys)
256// image: These pages are mapped into the view of an image section (backed by
257// file system)
258struct CommittedKBytes {
259 size_t priv;
260 size_t mapped;
261 size_t image;
262};
263
264// Free memory (Megabytes marked as free) in the 2G process address space.
265// total : total amount in megabytes marked as free. Maximum value is 2048.
266// largest : size of the largest contiguous amount of memory found. It is
267// always smaller or equal to FreeMBytes::total.
268// largest_ptr: starting address of the largest memory block.
269struct FreeMBytes {
270 size_t total;
271 size_t largest;
272 void* largest_ptr;
273};
274
275// Provides performance metrics for a specified process (CPU usage, memory and
276// IO counters). To use it, invoke CreateProcessMetrics() to get an instance
277// for a specific process, then access the information with the different get
278// methods.
279class ProcessMetrics {
280 public:
281 // Creates a ProcessMetrics for the specified process.
282 // The caller owns the returned object.
283 static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
284
285 ~ProcessMetrics();
286
287 // Returns the current space allocated for the pagefile, in bytes (these pages
288 // may or may not be in memory).
289 size_t GetPagefileUsage();
290 // Returns the peak space allocated for the pagefile, in bytes.
291 size_t GetPeakPagefileUsage();
292 // Returns the current working set size, in bytes.
293 size_t GetWorkingSetSize();
294 // Returns private usage, in bytes. Private bytes is the amount
295 // of memory currently allocated to a process that cannot be shared.
296 // Note: returns 0 on unsupported OSes: prior to XP SP2.
297 size_t GetPrivateBytes();
298 // Fills a CommittedKBytes with both resident and paged
299 // memory usage as per definition of CommittedBytes.
300 void GetCommittedKBytes(CommittedKBytes* usage);
301 // Fills a WorkingSetKBytes containing resident private and shared memory
302 // usage in bytes, as per definition of WorkingSetBytes.
303 bool GetWorkingSetKBytes(WorkingSetKBytes* ws_usage);
304
305 // Computes the current process available memory for allocation.
306 // It does a linear scan of the address space querying each memory region
307 // for its free (unallocated) status. It is useful for estimating the memory
308 // load and fragmentation.
309 bool CalculateFreeMemory(FreeMBytes* free);
310
311 // Returns the CPU usage in percent since the last time this method was
312 // called. The first time this method is called it returns 0 and will return
313 // the actual CPU info on subsequent calls.
314 // Note that on multi-processor machines, the CPU usage value is for all
315 // CPUs. So if you have 2 CPUs and your process is using all the cycles
316 // of 1 CPU and not the other CPU, this method returns 50.
317 int GetCPUUsage();
318
319 // Retrieves accounting information for all I/O operations performed by the
320 // process.
321 // If IO information is retrieved successfully, the function returns true
322 // and fills in the IO_COUNTERS passed in. The function returns false
323 // otherwise.
324 bool GetIOCounters(IoCounters* io_counters);
325
326 private:
327 explicit ProcessMetrics(ProcessHandle process);
328
329 ProcessHandle process_;
330
331 int processor_count_;
332
333 // Used to store the previous times so we can compute the CPU usage.
334 int64 last_time_;
335 int64 last_system_time_;
336
337 DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics);
338};
339
340// Enables low fragmentation heap (LFH) for every heaps of this process. This
341// won't have any effect on heaps created after this function call. It will not
342// modify data allocated in the heaps before calling this function. So it is
343// better to call this function early in initialization and again before
344// entering the main loop.
345// Note: Returns true on Windows 2000 without doing anything.
346bool EnableLowFragmentationHeap();
347
maruel@google.comc9d40872008-09-24 12:58:37348// Enable 'terminate on heap corruption' flag. Helps protect against heap
349// overflow. Has no effect if the OS doesn't provide the necessary facility.
350void EnableTerminationOnHeapCorruption();
351
deanm@google.comdb717282008-08-27 13:48:03352// If supported on the platform, and the user has sufficent rights, increase
353// the current process's scheduling priority to a high priority.
354void RaiseProcessToHighPriority();
355
brettw@google.com176aa482008-11-14 03:25:15356} // namespace base
initial.commitd7cae122008-07-26 21:49:38357
deanm@google.comdb717282008-08-27 13:48:03358#endif // BASE_PROCESS_UTIL_H_