|
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) || defined(__GLIBC__) |
|
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 inline ProcessArchitecture GetCurrentProcessArchitecture() |
|
69 { |
|
70 base::ProcessArchitecture currentArchitecture; |
|
71 #if defined(ARCH_CPU_X86) |
|
72 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 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 enum ChildPrivileges { |
|
130 PRIVILEGES_DEFAULT, |
|
131 PRIVILEGES_UNPRIVILEGED, |
|
132 PRIVILEGES_INHERIT, |
|
133 PRIVILEGES_LAST |
|
134 }; |
|
135 |
|
136 #if defined(OS_WIN) |
|
137 // Runs the given application name with the given command line. Normally, the |
|
138 // first command line argument should be the path to the process, and don't |
|
139 // forget to quote it. |
|
140 // |
|
141 // If wait is true, it will block and wait for the other process to finish, |
|
142 // otherwise, it will just continue asynchronously. |
|
143 // |
|
144 // Example (including literal quotes) |
|
145 // cmdline = "c:\windows\explorer.exe" -foo "c:\bar\" |
|
146 // |
|
147 // If process_handle is non-NULL, the process handle of the launched app will be |
|
148 // stored there on a successful launch. |
|
149 // NOTE: In this case, the caller is responsible for closing the handle so |
|
150 // that it doesn't leak! |
|
151 bool LaunchApp(const std::wstring& cmdline, |
|
152 bool wait, bool start_hidden, ProcessHandle* process_handle); |
|
153 #elif defined(OS_POSIX) |
|
154 // Runs the application specified in argv[0] with the command line argv. |
|
155 // Before launching all FDs open in the parent process will be marked as |
|
156 // close-on-exec. |fds_to_remap| defines a mapping of src fd->dest fd to |
|
157 // propagate FDs into the child process. |
|
158 // |
|
159 // As above, if wait is true, execute synchronously. The pid will be stored |
|
160 // in process_handle if that pointer is non-null. |
|
161 // |
|
162 // Note that the first argument in argv must point to the filename, |
|
163 // and must be fully specified. |
|
164 typedef std::vector<std::pair<int, int> > file_handle_mapping_vector; |
|
165 bool LaunchApp(const std::vector<std::string>& argv, |
|
166 const file_handle_mapping_vector& fds_to_remap, |
|
167 bool wait, ProcessHandle* process_handle); |
|
168 |
|
169 typedef std::map<std::string, std::string> environment_map; |
|
170 bool LaunchApp(const std::vector<std::string>& argv, |
|
171 const file_handle_mapping_vector& fds_to_remap, |
|
172 const environment_map& env_vars_to_set, |
|
173 ChildPrivileges privs, |
|
174 bool wait, ProcessHandle* process_handle, |
|
175 ProcessArchitecture arch=GetCurrentProcessArchitecture()); |
|
176 bool LaunchApp(const std::vector<std::string>& argv, |
|
177 const file_handle_mapping_vector& fds_to_remap, |
|
178 const environment_map& env_vars_to_set, |
|
179 bool wait, ProcessHandle* process_handle, |
|
180 ProcessArchitecture arch=GetCurrentProcessArchitecture()); |
|
181 #endif |
|
182 |
|
183 // Adjust the privileges of this process to match |privs|. Only |
|
184 // returns if privileges were successfully adjusted. |
|
185 void SetCurrentProcessPrivileges(ChildPrivileges privs); |
|
186 |
|
187 // Executes the application specified by cl. This function delegates to one |
|
188 // of the above two platform-specific functions. |
|
189 bool LaunchApp(const CommandLine& cl, |
|
190 bool wait, bool start_hidden, ProcessHandle* process_handle); |
|
191 |
|
192 // Used to filter processes by process ID. |
|
193 class ProcessFilter { |
|
194 public: |
|
195 // Returns true to indicate set-inclusion and false otherwise. This method |
|
196 // should not have side-effects and should be idempotent. |
|
197 virtual bool Includes(ProcessId pid, ProcessId parent_pid) const = 0; |
|
198 virtual ~ProcessFilter() { } |
|
199 }; |
|
200 |
|
201 // Attempts to kill the process identified by the given process |
|
202 // entry structure, giving it the specified exit code. If |wait| is true, wait |
|
203 // for the process to be actually terminated before returning. |
|
204 // Returns true if this is successful, false otherwise. |
|
205 bool KillProcess(ProcessHandle process, int exit_code, bool wait); |
|
206 |
|
207 // Get the termination status (exit code) of the process and return true if the |
|
208 // status indicates the process crashed. |child_exited| is set to true iff the |
|
209 // child process has terminated. (|child_exited| may be NULL.) |
|
210 // |
|
211 // On Windows, it is an error to call this if the process hasn't terminated |
|
212 // yet. On POSIX, |child_exited| is set correctly since we detect terminate in |
|
213 // a different manner on POSIX. |
|
214 bool DidProcessCrash(bool* child_exited, ProcessHandle handle); |
|
215 |
|
216 // This class provides a way to iterate through the list of processes |
|
217 // on the current machine that were started from the given executable |
|
218 // name. To use, create an instance and then call NextProcessEntry() |
|
219 // until it returns false. |
|
220 class NamedProcessIterator { |
|
221 public: |
|
222 NamedProcessIterator(const std::wstring& executable_name, |
|
223 const ProcessFilter* filter); |
|
224 ~NamedProcessIterator(); |
|
225 |
|
226 // If there's another process that matches the given executable name, |
|
227 // returns a const pointer to the corresponding PROCESSENTRY32. |
|
228 // If there are no more matching processes, returns NULL. |
|
229 // The returned pointer will remain valid until NextProcessEntry() |
|
230 // is called again or this NamedProcessIterator goes out of scope. |
|
231 const ProcessEntry* NextProcessEntry(); |
|
232 |
|
233 private: |
|
234 #if !defined(OS_BSD) || defined(__GLIBC__) |
|
235 // Determines whether there's another process (regardless of executable) |
|
236 // left in the list of all processes. Returns true and sets entry_ to |
|
237 // that process's info if there is one, false otherwise. |
|
238 bool CheckForNextProcess(); |
|
239 |
|
240 bool IncludeEntry(); |
|
241 |
|
242 // Initializes a PROCESSENTRY32 data structure so that it's ready for |
|
243 // use with Process32First/Process32Next. |
|
244 void InitProcessEntry(ProcessEntry* entry); |
|
245 |
|
246 std::wstring executable_name_; |
|
247 #endif |
|
248 |
|
249 #if defined(OS_WIN) |
|
250 HANDLE snapshot_; |
|
251 bool started_iteration_; |
|
252 #elif defined(OS_LINUX) || defined(__GLIBC__) |
|
253 DIR *procfs_dir_; |
|
254 #elif defined(OS_BSD) |
|
255 std::vector<ProcessEntry> content; |
|
256 size_t nextEntry; |
|
257 #elif defined(OS_MACOSX) |
|
258 std::vector<kinfo_proc> kinfo_procs_; |
|
259 size_t index_of_kinfo_proc_; |
|
260 #endif |
|
261 #if !defined(OS_BSD) || defined(__GLIBC__) |
|
262 ProcessEntry entry_; |
|
263 const ProcessFilter* filter_; |
|
264 #endif |
|
265 |
|
266 DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator); |
|
267 }; |
|
268 |
|
269 // Provides performance metrics for a specified process (CPU usage, memory and |
|
270 // IO counters). To use it, invoke CreateProcessMetrics() to get an instance |
|
271 // for a specific process, then access the information with the different get |
|
272 // methods. |
|
273 class ProcessMetrics { |
|
274 public: |
|
275 // Creates a ProcessMetrics for the specified process. |
|
276 // The caller owns the returned object. |
|
277 static ProcessMetrics* CreateProcessMetrics(ProcessHandle process); |
|
278 |
|
279 ~ProcessMetrics(); |
|
280 |
|
281 // Returns the CPU usage in percent since the last time this method was |
|
282 // called. The first time this method is called it returns 0 and will return |
|
283 // the actual CPU info on subsequent calls. |
|
284 // Note that on multi-processor machines, the CPU usage value is for all |
|
285 // CPUs. So if you have 2 CPUs and your process is using all the cycles |
|
286 // of 1 CPU and not the other CPU, this method returns 50. |
|
287 int GetCPUUsage(); |
|
288 |
|
289 private: |
|
290 explicit ProcessMetrics(ProcessHandle process); |
|
291 |
|
292 ProcessHandle process_; |
|
293 |
|
294 int processor_count_; |
|
295 |
|
296 // Used to store the previous times so we can compute the CPU usage. |
|
297 int64_t last_time_; |
|
298 int64_t last_system_time_; |
|
299 |
|
300 DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics); |
|
301 }; |
|
302 |
|
303 } // namespace base |
|
304 |
|
305 #if defined(OS_WIN) |
|
306 // Undo the windows.h damage |
|
307 #undef GetMessage |
|
308 #undef CreateEvent |
|
309 #undef GetClassName |
|
310 #undef GetBinaryType |
|
311 #endif |
|
312 |
|
313 #endif // BASE_PROCESS_UTIL_H_ |