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_
|