1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "perfetto/ext/base/subprocess.h"
18
19 #include "perfetto/base/build_config.h"
20
21 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
22 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
23 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
24
25 #include <fcntl.h>
26 #include <poll.h>
27 #include <signal.h>
28 #include <stdio.h>
29 #include <sys/resource.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 #include <unistd.h>
33
34 #include <algorithm>
35 #include <thread>
36 #include <tuple>
37
38 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
39 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
40 #include <sys/prctl.h>
41 #endif
42
43 #include "perfetto/base/logging.h"
44 #include "perfetto/base/time.h"
45 #include "perfetto/ext/base/utils.h"
46
47 // In MacOS this is not defined in any header.
48 extern "C" char** environ;
49
50 namespace perfetto {
51 namespace base {
52
53 namespace {
54
55 struct ChildProcessArgs {
56 Subprocess::Args* create_args;
57 const char* exec_cmd = nullptr;
58 std::vector<char*> argv;
59 std::vector<char*> env;
60 int stdin_pipe_rd = -1;
61 int stdouterr_pipe_wr = -1;
62 };
63
64 // Don't add any dynamic allocation in this function. This will be invoked
65 // under a fork(), potentially in a state where the allocator lock is held.
ChildProcess(ChildProcessArgs * args)66 void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
67 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
68 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
69 // In no case we want a child process to outlive its parent process. This is
70 // relevant for tests, so that a test failure/crash doesn't leave child
71 // processes around that get reparented to init.
72 prctl(PR_SET_PDEATHSIG, SIGKILL);
73 #endif
74
75 auto die = [args](const char* err) __attribute__((noreturn)) {
76 base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
77 base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
78 // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
79 // "In particular, the value 128 is used to indicate failure to execute
80 // another program in a subprocess. This convention is not universally
81 // obeyed, but it is a good idea to follow it in your programs."
82 _exit(128);
83 };
84
85 auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
86 int flags = fcntl(fd, F_GETFD, 0);
87 if (flags < 0)
88 die("fcntl(F_GETFD) failed");
89 flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
90 if (fcntl(fd, F_SETFD, flags) < 0)
91 die("fcntl(F_SETFD) failed");
92 };
93
94 if (getppid() == 1)
95 die("terminating because parent process died");
96
97 if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
98 die("Failed to dup2(STDIN)");
99 close(args->stdin_pipe_rd);
100
101 switch (args->create_args->stdout_mode) {
102 case Subprocess::kInherit:
103 break;
104 case Subprocess::kDevNull: {
105 if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
106 die("Failed to dup2(STDOUT)");
107 break;
108 }
109 case Subprocess::kBuffer:
110 if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
111 die("Failed to dup2(STDOUT)");
112 break;
113 case Subprocess::kFd:
114 if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
115 die("Failed to dup2(STDOUT)");
116 break;
117 }
118
119 switch (args->create_args->stderr_mode) {
120 case Subprocess::kInherit:
121 break;
122 case Subprocess::kDevNull: {
123 if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
124 die("Failed to dup2(STDERR)");
125 break;
126 }
127 case Subprocess::kBuffer:
128 if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
129 die("Failed to dup2(STDERR)");
130 break;
131 case Subprocess::kFd:
132 if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
133 die("Failed to dup2(STDERR)");
134 break;
135 }
136
137 // Close all FDs % stdin/out/err and the ones that the client explicitly
138 // asked to retain. The reason for this is twofold:
139 // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
140 // that didn't get marked as O_CLOEXEC by accident.
141 // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
142 // that would prevent the parent process to receive EOFs (tests usually use
143 // pipes as a synchronization mechanism between subprocesses).
144 const auto& preserve_fds = args->create_args->preserve_fds;
145 for (int i = 0; i < 512; i++) {
146 if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
147 i != args->stdouterr_pipe_wr &&
148 !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
149 close(i);
150 }
151 }
152
153 // Clears O_CLOEXEC from stdin/out/err. These are the only FDs that we want
154 // to be preserved after the exec().
155 set_fd_close_on_exec(STDIN_FILENO, false);
156 set_fd_close_on_exec(STDOUT_FILENO, false);
157 set_fd_close_on_exec(STDERR_FILENO, false);
158
159 // If the caller specified a std::function entrypoint, run that first.
160 if (args->create_args->posix_entrypoint_for_testing)
161 args->create_args->posix_entrypoint_for_testing();
162
163 // If the caller specified only an entrypoint, without any args, exit now.
164 // Otherwise proceed with the exec() below.
165 if (!args->exec_cmd)
166 _exit(0);
167
168 // If |args[0]| is a path use execv() (which takes a path), othewise use
169 // exevp(), which uses the shell and follows PATH.
170 if (strchr(args->exec_cmd, '/')) {
171 char** env = args->env.empty() ? environ : args->env.data();
172 execve(args->exec_cmd, args->argv.data(), env);
173 } else {
174 // There is no execvpe() on Mac.
175 if (!args->env.empty())
176 die("A full path is required for |exec_cmd| when setting |env|");
177 execvp(args->exec_cmd, args->argv.data());
178 }
179
180 // Reached only if execv fails.
181 die("execve() failed");
182 }
183
184 } // namespace
185
186 // static
187 const int Subprocess::kTimeoutSignal = SIGKILL;
188
Start()189 void Subprocess::Start() {
190 ChildProcessArgs proc_args;
191 proc_args.create_args = &args;
192
193 // Setup argv.
194 if (!args.exec_cmd.empty()) {
195 proc_args.exec_cmd = args.exec_cmd[0].c_str();
196 for (const std::string& arg : args.exec_cmd)
197 proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
198 proc_args.argv.push_back(nullptr);
199
200 if (!args.posix_argv0_override_for_testing.empty()) {
201 proc_args.argv[0] =
202 const_cast<char*>(args.posix_argv0_override_for_testing.c_str());
203 }
204 }
205
206 // Setup env.
207 if (!args.env.empty()) {
208 for (const std::string& str : args.env)
209 proc_args.env.push_back(const_cast<char*>(str.c_str()));
210 proc_args.env.push_back(nullptr);
211 }
212
213 // Setup the pipes for stdin/err redirection.
214 s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
215 proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
216 s_->stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
217 proc_args.stdouterr_pipe_wr = *s_->stdouterr_pipe.wr;
218
219 // Spawn the child process that will exec().
220 s_->pid = fork();
221 PERFETTO_CHECK(s_->pid >= 0);
222 if (s_->pid == 0) {
223 // Close the parent-ends of the pipes.
224 s_->stdin_pipe.wr.reset();
225 s_->stdouterr_pipe.rd.reset();
226 ChildProcess(&proc_args);
227 // ChildProcess() doesn't return, not even in case of failures.
228 PERFETTO_FATAL("not reached");
229 }
230
231 s_->status = kRunning;
232
233 // Close the child-end of the pipes.
234 // Deliberately NOT closing the s_->stdin_pipe.rd. This is to avoid crashing
235 // with a SIGPIPE if the process exits without consuming its stdin, while
236 // the parent tries to write() on the other end of the stdin pipe.
237 s_->stdouterr_pipe.wr.reset();
238 proc_args.create_args->out_fd.reset();
239
240 // Spawn a thread that is blocked on waitpid() and writes the termination
241 // status onto a pipe. The problem here is that waipid() doesn't have a
242 // timeout option and can't be passed to poll(). The alternative would be
243 // using a SIGCHLD handler, but anecdotally signal handlers introduce more
244 // problems than what they solve.
245 s_->exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
246
247 // Both ends of the pipe are closed after the thread.join().
248 int pid = s_->pid;
249 int exit_status_pipe_wr = s_->exit_status_pipe.wr.release();
250 auto* rusage = s_->rusage.get();
251 s_->waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
252 int pid_stat = -1;
253 struct rusage usg {};
254 int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
255 PERFETTO_CHECK(wait_res == pid);
256
257 auto tv_to_ms = [](const struct timeval& tv) {
258 return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
259 };
260 rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
261 rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
262 rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
263 rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
264 rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
265 rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
266 rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);
267
268 base::ignore_result(PERFETTO_EINTR(
269 write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
270 PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
271 });
272 }
273
Poll()274 Subprocess::Status Subprocess::Poll() {
275 if (s_->status != kRunning)
276 return s_->status; // Nothing to poll.
277 while (PollInternal(0 /* don't block*/)) {
278 }
279 return s_->status;
280 }
281
282 // |timeout_ms| semantic:
283 // -1: Block indefinitely.
284 // 0: Don't block, return immediately.
285 // >0: Block for at most X ms.
286 // Returns:
287 // True: Read at least one fd (so there might be more queued).
288 // False: if all fds reached quiescent (no data to read/write).
PollInternal(int poll_timeout_ms)289 bool Subprocess::PollInternal(int poll_timeout_ms) {
290 struct pollfd fds[3]{};
291 size_t num_fds = 0;
292 if (s_->exit_status_pipe.rd) {
293 fds[num_fds].fd = *s_->exit_status_pipe.rd;
294 fds[num_fds].events = POLLIN;
295 num_fds++;
296 }
297 if (s_->stdouterr_pipe.rd) {
298 fds[num_fds].fd = *s_->stdouterr_pipe.rd;
299 fds[num_fds].events = POLLIN;
300 num_fds++;
301 }
302 if (s_->stdin_pipe.wr) {
303 fds[num_fds].fd = *s_->stdin_pipe.wr;
304 fds[num_fds].events = POLLOUT;
305 num_fds++;
306 }
307
308 if (num_fds == 0)
309 return false;
310
311 auto nfds = static_cast<nfds_t>(num_fds);
312 int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
313 PERFETTO_CHECK(poll_res >= 0);
314
315 TryReadStdoutAndErr();
316 TryPushStdin();
317 TryReadExitStatus();
318
319 return poll_res > 0;
320 }
321
Wait(int timeout_ms)322 bool Subprocess::Wait(int timeout_ms) {
323 PERFETTO_CHECK(s_->status != kNotStarted);
324
325 // Break out of the loop only after both conditions are satisfied:
326 // - All stdout/stderr data has been read (if kBuffer).
327 // - The process exited.
328 // Note that the two events can happen arbitrary order. After the process
329 // exits, there might be still data in the pipe buffer, which we want to
330 // read fully.
331 //
332 // Instead, don't wait on the stdin to be fully written. The child process
333 // might exit prematurely (or crash). If that happens, we can end up in a
334 // state where the write(stdin_pipe_.wr) will never unblock.
335
336 const int64_t t_start = base::GetWallTimeMs().count();
337 while (s_->exit_status_pipe.rd || s_->stdouterr_pipe.rd) {
338 int poll_timeout_ms = -1; // Block until a FD is ready.
339 if (timeout_ms > 0) {
340 const int64_t now = GetWallTimeMs().count();
341 poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
342 if (poll_timeout_ms <= 0)
343 return false;
344 }
345 PollInternal(poll_timeout_ms);
346 } // while(...)
347 return true;
348 }
349
TryReadExitStatus()350 void Subprocess::TryReadExitStatus() {
351 if (!s_->exit_status_pipe.rd)
352 return;
353
354 int pid_stat = -1;
355 int64_t rsize = PERFETTO_EINTR(
356 read(*s_->exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
357 if (rsize < 0 && errno == EAGAIN)
358 return;
359
360 if (rsize > 0) {
361 PERFETTO_CHECK(rsize == sizeof(pid_stat));
362 } else if (rsize < 0) {
363 PERFETTO_PLOG("Subprocess read(s_->exit_status_pipe) failed");
364 }
365 s_->waitpid_thread.join();
366 s_->exit_status_pipe.rd.reset();
367
368 s_->status = kTerminated;
369 if (WIFEXITED(pid_stat)) {
370 s_->returncode = WEXITSTATUS(pid_stat);
371 } else if (WIFSIGNALED(pid_stat)) {
372 s_->returncode = 128 + WTERMSIG(pid_stat); // Follow bash convention.
373 } else {
374 PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
375 }
376 }
377
378 // If the stidn pipe is still open, push input data and close it at the end.
TryPushStdin()379 void Subprocess::TryPushStdin() {
380 if (!s_->stdin_pipe.wr)
381 return;
382
383 PERFETTO_DCHECK(args.input.empty() || s_->input_written < args.input.size());
384 if (!args.input.empty()) {
385 int64_t wsize =
386 PERFETTO_EINTR(write(*s_->stdin_pipe.wr, &args.input[s_->input_written],
387 args.input.size() - s_->input_written));
388 if (wsize < 0 && errno == EAGAIN)
389 return;
390
391 if (wsize >= 0) {
392 // Whether write() can return 0 is one of the greatest mysteries of UNIX.
393 // Just ignore it.
394 s_->input_written += static_cast<size_t>(wsize);
395 } else {
396 PERFETTO_PLOG("Subprocess write(stdin) failed");
397 s_->stdin_pipe.wr.reset();
398 }
399 }
400 PERFETTO_DCHECK(s_->input_written <= args.input.size());
401 if (s_->input_written == args.input.size())
402 s_->stdin_pipe.wr.reset(); // Close stdin.
403 }
404
TryReadStdoutAndErr()405 void Subprocess::TryReadStdoutAndErr() {
406 if (!s_->stdouterr_pipe.rd)
407 return;
408 char buf[4096];
409 int64_t rsize =
410 PERFETTO_EINTR(read(*s_->stdouterr_pipe.rd, buf, sizeof(buf)));
411 if (rsize < 0 && errno == EAGAIN)
412 return;
413
414 if (rsize > 0) {
415 s_->output.append(buf, static_cast<size_t>(rsize));
416 } else if (rsize == 0 /* EOF */) {
417 s_->stdouterr_pipe.rd.reset();
418 } else {
419 PERFETTO_PLOG("Subprocess read(stdout/err) failed");
420 s_->stdouterr_pipe.rd.reset();
421 }
422 }
423
KillAndWaitForTermination(int sig_num)424 void Subprocess::KillAndWaitForTermination(int sig_num) {
425 kill(s_->pid, sig_num ? sig_num : SIGKILL);
426 Wait();
427 // TryReadExitStatus must have joined the thread.
428 PERFETTO_DCHECK(!s_->waitpid_thread.joinable());
429 }
430
431 } // namespace base
432 } // namespace perfetto
433
434 #endif // PERFETTO_OS_LINUX || PERFETTO_OS_ANDROID || PERFETTO_OS_APPLE
435