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