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