• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   if (args->create_args->posix_proc_group_id.has_value()) {
86     if (setpgid(0 /*self*/, args->create_args->posix_proc_group_id.value())) {
87       die("setpgid() failed");
88     }
89   }
90 
91   auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
92     int flags = fcntl(fd, F_GETFD, 0);
93     if (flags < 0)
94       die("fcntl(F_GETFD) failed");
95     flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
96     if (fcntl(fd, F_SETFD, flags) < 0)
97       die("fcntl(F_SETFD) failed");
98   };
99 
100   if (getppid() == 1)
101     die("terminating because parent process died");
102 
103   switch (args->create_args->stdin_mode) {
104     case Subprocess::InputMode::kBuffer:
105       if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
106         die("Failed to dup2(STDIN)");
107       close(args->stdin_pipe_rd);
108       break;
109     case Subprocess::InputMode::kDevNull:
110       if (dup2(open("/dev/null", O_RDONLY), STDIN_FILENO) == -1)
111         die("Failed to dup2(STDOUT)");
112       break;
113   }
114 
115   switch (args->create_args->stdout_mode) {
116     case Subprocess::OutputMode::kInherit:
117       break;
118     case Subprocess::OutputMode::kDevNull: {
119       if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
120         die("Failed to dup2(STDOUT)");
121       break;
122     }
123     case Subprocess::OutputMode::kBuffer:
124       if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
125         die("Failed to dup2(STDOUT)");
126       break;
127     case Subprocess::OutputMode::kFd:
128       if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
129         die("Failed to dup2(STDOUT)");
130       break;
131   }
132 
133   switch (args->create_args->stderr_mode) {
134     case Subprocess::OutputMode::kInherit:
135       break;
136     case Subprocess::OutputMode::kDevNull: {
137       if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
138         die("Failed to dup2(STDERR)");
139       break;
140     }
141     case Subprocess::OutputMode::kBuffer:
142       if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
143         die("Failed to dup2(STDERR)");
144       break;
145     case Subprocess::OutputMode::kFd:
146       if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
147         die("Failed to dup2(STDERR)");
148       break;
149   }
150 
151   // Close all FDs % stdin/out/err and the ones that the client explicitly
152   // asked to retain. The reason for this is twofold:
153   // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
154   //    that didn't get marked as O_CLOEXEC by accident.
155   // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
156   //    that would prevent the parent process to receive EOFs (tests usually use
157   //    pipes as a synchronization mechanism between subprocesses).
158   const auto& preserve_fds = args->create_args->preserve_fds;
159   for (int i = 0; i < 512; i++) {
160     if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
161         i != args->stdouterr_pipe_wr &&
162         !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
163       close(i);
164     }
165   }
166 
167   // Clears O_CLOEXEC from stdin/out/err and the |preserve_fds| list. These are
168   // the only FDs that we want to be preserved after the exec().
169   set_fd_close_on_exec(STDIN_FILENO, false);
170   set_fd_close_on_exec(STDOUT_FILENO, false);
171   set_fd_close_on_exec(STDERR_FILENO, false);
172 
173   for (auto fd : preserve_fds)
174     set_fd_close_on_exec(fd, false);
175 
176   // If the caller specified a std::function entrypoint, run that first.
177   if (args->create_args->posix_entrypoint_for_testing)
178     args->create_args->posix_entrypoint_for_testing();
179 
180   // If the caller specified only an entrypoint, without any args, exit now.
181   // Otherwise proceed with the exec() below.
182   if (!args->exec_cmd)
183     _exit(0);
184 
185   // If |args[0]| is a path use execv() (which takes a path), othewise use
186   // exevp(), which uses the shell and follows PATH.
187   if (strchr(args->exec_cmd, '/')) {
188     char** env = args->env.empty() ? environ : args->env.data();
189     execve(args->exec_cmd, args->argv.data(), env);
190   } else {
191     // There is no execvpe() on Mac.
192     if (!args->env.empty())
193       die("A full path is required for |exec_cmd| when setting |env|");
194     execvp(args->exec_cmd, args->argv.data());
195   }
196 
197   // Reached only if execv fails.
198   die("execve() failed");
199 }
200 
201 }  // namespace
202 
203 // static
204 const int Subprocess::kTimeoutSignal = SIGKILL;
205 
Start()206 void Subprocess::Start() {
207   ChildProcessArgs proc_args;
208   proc_args.create_args = &args;
209 
210   // Setup argv.
211   if (!args.exec_cmd.empty()) {
212     proc_args.exec_cmd = args.exec_cmd[0].c_str();
213     for (const std::string& arg : args.exec_cmd)
214       proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
215     proc_args.argv.push_back(nullptr);
216 
217     if (!args.posix_argv0_override_for_testing.empty()) {
218       proc_args.argv[0] =
219           const_cast<char*>(args.posix_argv0_override_for_testing.c_str());
220     }
221   }
222 
223   // Setup env.
224   if (!args.env.empty()) {
225     for (const std::string& str : args.env)
226       proc_args.env.push_back(const_cast<char*>(str.c_str()));
227     proc_args.env.push_back(nullptr);
228   }
229 
230   // Setup the pipes for stdin/err redirection.
231   if (args.stdin_mode == InputMode::kBuffer) {
232     s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
233     proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
234   }
235   s_->stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
236   proc_args.stdouterr_pipe_wr = *s_->stdouterr_pipe.wr;
237 
238   // Spawn the child process that will exec().
239   s_->pid = fork();
240   PERFETTO_CHECK(s_->pid >= 0);
241   if (s_->pid == 0) {
242     // Close the parent-ends of the pipes.
243     s_->stdin_pipe.wr.reset();
244     s_->stdouterr_pipe.rd.reset();
245     ChildProcess(&proc_args);
246     // ChildProcess() doesn't return, not even in case of failures.
247     PERFETTO_FATAL("not reached");
248   }
249 
250   s_->status = kRunning;
251 
252   // Close the child-end of the pipes.
253   // Deliberately NOT closing the s_->stdin_pipe.rd. This is to avoid crashing
254   // with a SIGPIPE if the process exits without consuming its stdin, while
255   // the parent tries to write() on the other end of the stdin pipe.
256   s_->stdouterr_pipe.wr.reset();
257   proc_args.create_args->out_fd.reset();
258 
259   // Spawn a thread that is blocked on waitpid() and writes the termination
260   // status onto a pipe. The problem here is that waipid() doesn't have a
261   // timeout option and can't be passed to poll(). The alternative would be
262   // using a SIGCHLD handler, but anecdotally signal handlers introduce more
263   // problems than what they solve.
264   s_->exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
265 
266   // Both ends of the pipe are closed after the thread.join().
267   int pid = s_->pid;
268   int exit_status_pipe_wr = s_->exit_status_pipe.wr.release();
269   auto* rusage = s_->rusage.get();
270   s_->waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
271     int pid_stat = -1;
272     struct rusage usg {};
273     int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
274     PERFETTO_CHECK(wait_res == pid);
275 
276     auto tv_to_ms = [](const struct timeval& tv) {
277       return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
278     };
279     rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
280     rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
281     rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
282     rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
283     rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
284     rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
285     rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);
286 
287     base::ignore_result(PERFETTO_EINTR(
288         write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
289     PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
290   });
291 }
292 
Poll()293 Subprocess::Status Subprocess::Poll() {
294   if (s_->status != kRunning)
295     return s_->status;  // Nothing to poll.
296   while (PollInternal(0 /* don't block*/)) {
297   }
298   return s_->status;
299 }
300 
301 // |timeout_ms| semantic:
302 //   -1: Block indefinitely.
303 //    0: Don't block, return immediately.
304 //   >0: Block for at most X ms.
305 // Returns:
306 //  True: Read at least one fd (so there might be more queued).
307 //  False: if all fds reached quiescent (no data to read/write).
PollInternal(int poll_timeout_ms)308 bool Subprocess::PollInternal(int poll_timeout_ms) {
309   struct pollfd fds[3]{};
310   size_t num_fds = 0;
311   if (s_->exit_status_pipe.rd) {
312     fds[num_fds].fd = *s_->exit_status_pipe.rd;
313     fds[num_fds].events = POLLIN;
314     num_fds++;
315   }
316   if (s_->stdouterr_pipe.rd) {
317     fds[num_fds].fd = *s_->stdouterr_pipe.rd;
318     fds[num_fds].events = POLLIN;
319     num_fds++;
320   }
321   if (s_->stdin_pipe.wr) {
322     fds[num_fds].fd = *s_->stdin_pipe.wr;
323     fds[num_fds].events = POLLOUT;
324     num_fds++;
325   }
326 
327   if (num_fds == 0)
328     return false;
329 
330   auto nfds = static_cast<nfds_t>(num_fds);
331   int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
332   PERFETTO_CHECK(poll_res >= 0);
333 
334   TryReadStdoutAndErr();
335   TryPushStdin();
336   TryReadExitStatus();
337 
338   return poll_res > 0;
339 }
340 
Wait(int timeout_ms)341 bool Subprocess::Wait(int timeout_ms) {
342   PERFETTO_CHECK(s_->status != kNotStarted);
343 
344   // Break out of the loop only after both conditions are satisfied:
345   // - All stdout/stderr data has been read (if kBuffer).
346   // - The process exited.
347   // Note that the two events can happen arbitrary order. After the process
348   // exits, there might be still data in the pipe buffer, which we want to
349   // read fully.
350   //
351   // Instead, don't wait on the stdin to be fully written. The child process
352   // might exit prematurely (or crash). If that happens, we can end up in a
353   // state where the write(stdin_pipe_.wr) will never unblock.
354 
355   const int64_t t_start = base::GetWallTimeMs().count();
356   while (s_->exit_status_pipe.rd || s_->stdouterr_pipe.rd) {
357     int poll_timeout_ms = -1;  // Block until a FD is ready.
358     if (timeout_ms > 0) {
359       const int64_t now = GetWallTimeMs().count();
360       poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
361       if (poll_timeout_ms <= 0)
362         return false;
363     }
364     PollInternal(poll_timeout_ms);
365   }  // while(...)
366   return true;
367 }
368 
TryReadExitStatus()369 void Subprocess::TryReadExitStatus() {
370   if (!s_->exit_status_pipe.rd)
371     return;
372 
373   int pid_stat = -1;
374   int64_t rsize = PERFETTO_EINTR(
375       read(*s_->exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
376   if (rsize < 0 && errno == EAGAIN)
377     return;
378 
379   if (rsize > 0) {
380     PERFETTO_CHECK(rsize == sizeof(pid_stat));
381   } else if (rsize < 0) {
382     PERFETTO_PLOG("Subprocess read(s_->exit_status_pipe) failed");
383   }
384   s_->waitpid_thread.join();
385   s_->exit_status_pipe.rd.reset();
386 
387   s_->status = kTerminated;
388   if (WIFEXITED(pid_stat)) {
389     s_->returncode = WEXITSTATUS(pid_stat);
390   } else if (WIFSIGNALED(pid_stat)) {
391     s_->returncode = 128 + WTERMSIG(pid_stat);  // Follow bash convention.
392   } else {
393     PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
394   }
395 }
396 
397 // If the stidn pipe is still open, push input data and close it at the end.
TryPushStdin()398 void Subprocess::TryPushStdin() {
399   if (!s_->stdin_pipe.wr)
400     return;
401 
402   PERFETTO_DCHECK(args.input.empty() || s_->input_written < args.input.size());
403   if (!args.input.empty()) {
404     int64_t wsize =
405         PERFETTO_EINTR(write(*s_->stdin_pipe.wr, &args.input[s_->input_written],
406                              args.input.size() - s_->input_written));
407     if (wsize < 0 && errno == EAGAIN)
408       return;
409 
410     if (wsize >= 0) {
411       // Whether write() can return 0 is one of the greatest mysteries of UNIX.
412       // Just ignore it.
413       s_->input_written += static_cast<size_t>(wsize);
414     } else {
415       PERFETTO_PLOG("Subprocess write(stdin) failed");
416       s_->stdin_pipe.wr.reset();
417     }
418   }
419   PERFETTO_DCHECK(s_->input_written <= args.input.size());
420   if (s_->input_written == args.input.size())
421     s_->stdin_pipe.wr.reset();  // Close stdin.
422 }
423 
TryReadStdoutAndErr()424 void Subprocess::TryReadStdoutAndErr() {
425   if (!s_->stdouterr_pipe.rd)
426     return;
427   char buf[4096];
428   int64_t rsize =
429       PERFETTO_EINTR(read(*s_->stdouterr_pipe.rd, buf, sizeof(buf)));
430   if (rsize < 0 && errno == EAGAIN)
431     return;
432 
433   if (rsize > 0) {
434     s_->output.append(buf, static_cast<size_t>(rsize));
435   } else if (rsize == 0 /* EOF */) {
436     s_->stdouterr_pipe.rd.reset();
437   } else {
438     PERFETTO_PLOG("Subprocess read(stdout/err) failed");
439     s_->stdouterr_pipe.rd.reset();
440   }
441 }
442 
KillAndWaitForTermination(int sig_num)443 void Subprocess::KillAndWaitForTermination(int sig_num) {
444   kill(s_->pid, sig_num ? sig_num : SIGKILL);
445   Wait();
446   // TryReadExitStatus must have joined the thread.
447   PERFETTO_DCHECK(!s_->waitpid_thread.joinable());
448 }
449 
450 }  // namespace base
451 }  // namespace perfetto
452 
453 #endif  // PERFETTO_OS_LINUX || PERFETTO_OS_ANDROID || PERFETTO_OS_APPLE
454