[go: nahoru, domu]

blob: f00016ee165e0d2ca80765c837ff3adc1a891280 [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>
23
estade@chromium.orgfb7f9be2008-10-22 01:15:4724#include "base/command_line.h"
initial.commitd7cae122008-07-26 21:49:3825#include "base/process.h"
26
paulg@google.com61659062008-08-06 01:04:1827#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:3828typedef PROCESSENTRY32 ProcessEntry;
29typedef IO_COUNTERS IoCounters;
paulg@google.com61659062008-08-06 01:04:1830#elif defined(OS_POSIX)
dkegel@google.comab0e2222008-10-31 20:19:4331struct ProcessEntry {
32 int pid;
33 int ppid;
34 char szExeFile[NAME_MAX+1];
35};
36
evanm@google.com0b100bc82008-10-14 20:49:1637struct IoCounters {
38 unsigned long long ReadOperationCount;
39 unsigned long long WriteOperationCount;
40 unsigned long long OtherOperationCount;
41 unsigned long long ReadTransferCount;
42 unsigned long long WriteTransferCount;
43 unsigned long long OtherTransferCount;
44};
initial.commitd7cae122008-07-26 21:49:3845#endif
46
brettw@google.com176aa482008-11-14 03:25:1547namespace base {
initial.commitd7cae122008-07-26 21:49:3848
cpu@google.comeef576f2008-11-03 23:28:0649// A minimalistic but hopefully cross-platform set of exit codes.
50// Do not change the enumeration values or you will break third-party
51// installers.
52enum {
53 PROCESS_END_NORMAL_TERMINATON = 0,
54 PROCESS_END_KILLED_BY_USER = 1,
55 PROCESS_END_PROCESS_WAS_HUNG = 2
56};
57
initial.commitd7cae122008-07-26 21:49:3858// Returns the id of the current process.
59int GetCurrentProcId();
60
erikkay@google.com113ab132008-09-18 20:42:5561// Returns the ProcessHandle of the current process.
62ProcessHandle GetCurrentProcessHandle();
63
cpu@google.comeef576f2008-11-03 23:28:0664// Returns the unique ID for the specified process. This is functionally the
initial.commitd7cae122008-07-26 21:49:3865// same as Windows' GetProcessId(), but works on versions of Windows before
66// Win XP SP1 as well.
67int GetProcId(ProcessHandle process);
68
jeremy@chromium.orgfa3097a6a52008-12-17 22:41:5069#if defined(OS_POSIX)
70// Returns the maximum number of files that a process can have open.
71// Returns 0 on error.
72int GetMaxFilesOpenInProcess();
73#endif
74
estade@chromium.orgfb7f9be2008-10-22 01:15:4775#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:3876// Runs the given application name with the given command line. Normally, the
77// first command line argument should be the path to the process, and don't
78// forget to quote it.
79//
80// If wait is true, it will block and wait for the other process to finish,
81// otherwise, it will just continue asynchronously.
82//
83// Example (including literal quotes)
84// cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
85//
86// If process_handle is non-NULL, the process handle of the launched app will be
87// stored there on a successful launch.
88// NOTE: In this case, the caller is responsible for closing the handle so
89// that it doesn't leak!
90bool LaunchApp(const std::wstring& cmdline,
estade@chromium.orgfb7f9be2008-10-22 01:15:4791 bool wait, bool start_hidden, ProcessHandle* process_handle);
92#elif defined(OS_POSIX)
93// Runs the application specified in argv[0] with the command line argv.
jeremy@chromium.orgfa3097a6a52008-12-17 22:41:5094// Before launching all FDs open in the parent process will be marked as
95// close-on-exec. |fds_to_remap| defines a mapping of src fd->dest fd to
96// propagate FDs into the child process.
estade@chromium.orgfb7f9be2008-10-22 01:15:4797//
98// As above, if wait is true, execute synchronously. The pid will be stored
99// in process_handle if that pointer is non-null.
100//
101// Note that the first argument in argv must point to the filename,
102// and must be fully specified.
jeremy@chromium.orgfa3097a6a52008-12-17 22:41:50103typedef std::vector<std::pair<int, int> > file_handle_mapping_vector;
estade@chromium.orgfb7f9be2008-10-22 01:15:47104bool LaunchApp(const std::vector<std::string>& argv,
jeremy@chromium.orgfa3097a6a52008-12-17 22:41:50105 const file_handle_mapping_vector& fds_to_remap,
estade@chromium.orgfb7f9be2008-10-22 01:15:47106 bool wait, ProcessHandle* process_handle);
107#endif
108
109// Execute the application specified by cl. This function delegates to one
110// of the above two platform-specific functions.
111bool LaunchApp(const CommandLine& cl,
initial.commitd7cae122008-07-26 21:49:38112 bool wait, bool start_hidden, ProcessHandle* process_handle);
113
114// Used to filter processes by process ID.
115class ProcessFilter {
116 public:
117 // Returns true to indicate set-inclusion and false otherwise. This method
118 // should not have side-effects and should be idempotent.
119 virtual bool Includes(uint32 pid, uint32 parent_pid) const = 0;
avi@google.comdd950aa2008-08-12 21:24:39120 virtual ~ProcessFilter() { }
initial.commitd7cae122008-07-26 21:49:38121};
122
123// Returns the number of processes on the machine that are running from the
124// given executable name. If filter is non-null, then only processes selected
125// by the filter will be counted.
126int GetProcessCount(const std::wstring& executable_name,
127 const ProcessFilter* filter);
128
129// Attempts to kill all the processes on the current machine that were launched
130// from the given executable name, ending them with the given exit code. If
131// filter is non-null, then only processes selected by the filter are killed.
132// Returns false if all processes were able to be killed off, false if at least
133// one couldn't be killed.
134bool KillProcesses(const std::wstring& executable_name, int exit_code,
135 const ProcessFilter* filter);
136
137// Attempts to kill the process identified by the given process
138// entry structure, giving it the specified exit code. If |wait| is true, wait
139// for the process to be actually terminated before returning.
140// Returns true if this is successful, false otherwise.
141bool KillProcess(int process_id, int exit_code, bool wait);
agl@chromium.orgdfe14862009-01-22 01:23:11142#if defined(OS_WIN)
143bool KillProcess(HANDLE process, int exit_code, bool wait);
144#endif
initial.commitd7cae122008-07-26 21:49:38145
146// Get the termination status (exit code) of the process and return true if the
147// status indicates the process crashed. It is an error to call this if the
148// process hasn't terminated yet.
149bool DidProcessCrash(ProcessHandle handle);
150
phajdan.jr@chromium.orgc7856632009-01-13 17:38:49151// Waits for process to exit. In POSIX systems, if the process hasn't been
152// signaled then puts the exit code in |exit_code|; otherwise it's considered
153// a failure. On Windows |exit_code| is always filled. Returns true on success,
154// and closes |handle| in any case.
155bool WaitForExitCode(ProcessHandle handle, int* exit_code);
156
initial.commitd7cae122008-07-26 21:49:38157// Wait for all the processes based on the named executable to exit. If filter
158// is non-null, then only processes selected by the filter are waited on.
159// Returns after all processes have exited or wait_milliseconds have expired.
160// Returns true if all the processes exited, false otherwise.
161bool WaitForProcessesToExit(const std::wstring& executable_name,
162 int wait_milliseconds,
163 const ProcessFilter* filter);
164
estade@chromium.orgfb7f9be2008-10-22 01:15:47165// Wait for a single process to exit. Return true if it exited cleanly within
166// the given time limit.
167bool WaitForSingleProcess(ProcessHandle handle,
168 int wait_milliseconds);
169
initial.commitd7cae122008-07-26 21:49:38170// Waits a certain amount of time (can be 0) for all the processes with a given
171// executable name to exit, then kills off any of them that are still around.
172// If filter is non-null, then only processes selected by the filter are waited
173// on. Killed processes are ended with the given exit code. Returns false if
174// any processes needed to be killed, true if they all exited cleanly within
175// the wait_milliseconds delay.
176bool CleanupProcesses(const std::wstring& executable_name,
177 int wait_milliseconds,
178 int exit_code,
179 const ProcessFilter* filter);
180
181// This class provides a way to iterate through the list of processes
182// on the current machine that were started from the given executable
183// name. To use, create an instance and then call NextProcessEntry()
184// until it returns false.
185class NamedProcessIterator {
186 public:
187 NamedProcessIterator(const std::wstring& executable_name,
188 const ProcessFilter* filter);
189 ~NamedProcessIterator();
190
191 // If there's another process that matches the given executable name,
192 // returns a const pointer to the corresponding PROCESSENTRY32.
193 // If there are no more matching processes, returns NULL.
194 // The returned pointer will remain valid until NextProcessEntry()
195 // is called again or this NamedProcessIterator goes out of scope.
196 const ProcessEntry* NextProcessEntry();
197
198 private:
199 // Determines whether there's another process (regardless of executable)
200 // left in the list of all processes. Returns true and sets entry_ to
201 // that process's info if there is one, false otherwise.
202 bool CheckForNextProcess();
203
204 bool IncludeEntry();
205
206 // Initializes a PROCESSENTRY32 data structure so that it's ready for
207 // use with Process32First/Process32Next.
208 void InitProcessEntry(ProcessEntry* entry);
209
210 std::wstring executable_name_;
dkegel@google.comab0e2222008-10-31 20:19:43211
212#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:38213 HANDLE snapshot_;
initial.commitd7cae122008-07-26 21:49:38214 bool started_iteration_;
dkegel@google.comab0e2222008-10-31 20:19:43215#elif defined(OS_LINUX)
216 DIR *procfs_dir_;
217#elif defined(OS_MACOSX)
218 // probably kvm_t *kvmd_;
219#endif
220
initial.commitd7cae122008-07-26 21:49:38221 ProcessEntry entry_;
222 const ProcessFilter* filter_;
223
224 DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator);
225};
226
227// Working Set (resident) memory usage broken down by
228// priv (private): These pages (kbytes) cannot be shared with any other process.
229// shareable: These pages (kbytes) can be shared with other processes under
230// the right circumstances.
231// shared : These pages (kbytes) are currently shared with at least one
232// other process.
233struct WorkingSetKBytes {
234 size_t priv;
235 size_t shareable;
236 size_t shared;
237};
238
239// Committed (resident + paged) memory usage broken down by
240// private: These pages cannot be shared with any other process.
241// mapped: These pages are mapped into the view of a section (backed by
242// pagefile.sys)
243// image: These pages are mapped into the view of an image section (backed by
244// file system)
245struct CommittedKBytes {
246 size_t priv;
247 size_t mapped;
248 size_t image;
249};
250
251// Free memory (Megabytes marked as free) in the 2G process address space.
252// total : total amount in megabytes marked as free. Maximum value is 2048.
253// largest : size of the largest contiguous amount of memory found. It is
254// always smaller or equal to FreeMBytes::total.
255// largest_ptr: starting address of the largest memory block.
256struct FreeMBytes {
257 size_t total;
258 size_t largest;
259 void* largest_ptr;
260};
261
262// Provides performance metrics for a specified process (CPU usage, memory and
263// IO counters). To use it, invoke CreateProcessMetrics() to get an instance
264// for a specific process, then access the information with the different get
265// methods.
266class ProcessMetrics {
267 public:
268 // Creates a ProcessMetrics for the specified process.
269 // The caller owns the returned object.
270 static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
271
272 ~ProcessMetrics();
273
274 // Returns the current space allocated for the pagefile, in bytes (these pages
275 // may or may not be in memory).
276 size_t GetPagefileUsage();
277 // Returns the peak space allocated for the pagefile, in bytes.
278 size_t GetPeakPagefileUsage();
279 // Returns the current working set size, in bytes.
280 size_t GetWorkingSetSize();
281 // Returns private usage, in bytes. Private bytes is the amount
282 // of memory currently allocated to a process that cannot be shared.
283 // Note: returns 0 on unsupported OSes: prior to XP SP2.
284 size_t GetPrivateBytes();
285 // Fills a CommittedKBytes with both resident and paged
286 // memory usage as per definition of CommittedBytes.
287 void GetCommittedKBytes(CommittedKBytes* usage);
288 // Fills a WorkingSetKBytes containing resident private and shared memory
289 // usage in bytes, as per definition of WorkingSetBytes.
290 bool GetWorkingSetKBytes(WorkingSetKBytes* ws_usage);
291
292 // Computes the current process available memory for allocation.
293 // It does a linear scan of the address space querying each memory region
294 // for its free (unallocated) status. It is useful for estimating the memory
295 // load and fragmentation.
296 bool CalculateFreeMemory(FreeMBytes* free);
297
298 // Returns the CPU usage in percent since the last time this method was
299 // called. The first time this method is called it returns 0 and will return
300 // the actual CPU info on subsequent calls.
301 // Note that on multi-processor machines, the CPU usage value is for all
302 // CPUs. So if you have 2 CPUs and your process is using all the cycles
303 // of 1 CPU and not the other CPU, this method returns 50.
304 int GetCPUUsage();
305
306 // Retrieves accounting information for all I/O operations performed by the
307 // process.
308 // If IO information is retrieved successfully, the function returns true
309 // and fills in the IO_COUNTERS passed in. The function returns false
310 // otherwise.
311 bool GetIOCounters(IoCounters* io_counters);
312
313 private:
314 explicit ProcessMetrics(ProcessHandle process);
315
316 ProcessHandle process_;
317
318 int processor_count_;
319
320 // Used to store the previous times so we can compute the CPU usage.
321 int64 last_time_;
322 int64 last_system_time_;
323
324 DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics);
325};
326
327// Enables low fragmentation heap (LFH) for every heaps of this process. This
328// won't have any effect on heaps created after this function call. It will not
329// modify data allocated in the heaps before calling this function. So it is
330// better to call this function early in initialization and again before
331// entering the main loop.
332// Note: Returns true on Windows 2000 without doing anything.
333bool EnableLowFragmentationHeap();
334
maruel@google.comc9d40872008-09-24 12:58:37335// Enable 'terminate on heap corruption' flag. Helps protect against heap
336// overflow. Has no effect if the OS doesn't provide the necessary facility.
337void EnableTerminationOnHeapCorruption();
338
deanm@google.comdb717282008-08-27 13:48:03339// If supported on the platform, and the user has sufficent rights, increase
340// the current process's scheduling priority to a high priority.
341void RaiseProcessToHighPriority();
342
brettw@google.com176aa482008-11-14 03:25:15343} // namespace base
initial.commitd7cae122008-07-26 21:49:38344
deanm@google.comdb717282008-08-27 13:48:03345#endif // BASE_PROCESS_UTIL_H_