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