1 /*
2  * Copyright (C) 2018 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 "src/ftrace_reader/atrace_wrapper.h"
18 
19 #include <fcntl.h>
20 #include <stdint.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <sys/wait.h>
25 #include <unistd.h>
26 
27 #include "perfetto/base/logging.h"
28 
29 namespace perfetto {
30 
31 namespace {
32 
33 RunAtraceFunction g_run_atrace_for_testing = nullptr;
34 
35 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
36 // Args should include "atrace" for argv[0].
37 bool ExecvAtrace(const std::vector<std::string>& args) {
38   int status = 1;
39 
40   std::vector<char*> argv;
41   // args, and then a null.
42   argv.reserve(1 + args.size());
43   for (const auto& arg : args)
44     argv.push_back(const_cast<char*>(arg.c_str()));
45   argv.push_back(nullptr);
46 
47   pid_t pid = fork();
48   PERFETTO_CHECK(pid >= 0);
49   if (pid == 0) {
50     // Close stdin/out/err + any file descriptor that we might have mistakenly
51     // not marked as FD_CLOEXEC.
52     for (int i = 0; i < 128; i++)
53       close(i);
54     execv("/system/bin/atrace", &argv[0]);
55     // Reached only if execv fails.
56     _exit(1);
57   }
58   PERFETTO_EINTR(waitpid(pid, &status, 0));
59   return status == 0;
60 }
61 #endif
62 
63 }  // namespace
64 
65 bool RunAtrace(const std::vector<std::string>& args) {
66   if (g_run_atrace_for_testing)
67     return g_run_atrace_for_testing(args);
68 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
69   return ExecvAtrace(args);
70 #else
71   PERFETTO_LOG("Atrace only supported on Android.");
72   return false;
73 #endif
74 }
75 
76 void SetRunAtraceForTesting(RunAtraceFunction f) {
77   g_run_atrace_for_testing = f;
78 }
79 
80 }  // namespace perfetto
81