blob: 311c1cbd91448d583e1f92dfce6999b764979b2a [file] [log] [blame]
Hector Dearmanc20f2212018-03-08 10:39:00 +00001/*
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
Primiano Tucci3cbb10a2018-04-10 17:52:40 +010017#include "src/ftrace_reader/atrace_wrapper.h"
Hector Dearmanc20f2212018-03-08 10:39:00 +000018
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
29namespace perfetto {
30
31namespace {
32
33RunAtraceFunction g_run_atrace_for_testing = nullptr;
34
35#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
36// Args should include "atrace" for argv[0].
37bool 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
65bool 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
76void SetRunAtraceForTesting(RunAtraceFunction f) {
77 g_run_atrace_for_testing = f;
78}
79
80} // namespace perfetto