1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2020 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker *
4*6dbdd20aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker *
8*6dbdd20aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker *
10*6dbdd20aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker */
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/utils.h"
18*6dbdd20aSAndroid Build Coastguard Worker
19*6dbdd20aSAndroid Build Coastguard Worker #include <string>
20*6dbdd20aSAndroid Build Coastguard Worker
21*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/build_config.h"
22*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/file_utils.h"
24*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/pipe.h"
25*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/string_utils.h"
26*6dbdd20aSAndroid Build Coastguard Worker
27*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
28*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
29*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) || \
30*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
31*6dbdd20aSAndroid Build Coastguard Worker #include <limits.h>
32*6dbdd20aSAndroid Build Coastguard Worker #include <stdlib.h> // For _exit()
33*6dbdd20aSAndroid Build Coastguard Worker #include <unistd.h> // For getpagesize() and geteuid() & fork()
34*6dbdd20aSAndroid Build Coastguard Worker #endif
35*6dbdd20aSAndroid Build Coastguard Worker
36*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
37*6dbdd20aSAndroid Build Coastguard Worker #include <mach-o/dyld.h>
38*6dbdd20aSAndroid Build Coastguard Worker #include <mach/vm_page_size.h>
39*6dbdd20aSAndroid Build Coastguard Worker #endif
40*6dbdd20aSAndroid Build Coastguard Worker
41*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
42*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
43*6dbdd20aSAndroid Build Coastguard Worker #include <sys/prctl.h>
44*6dbdd20aSAndroid Build Coastguard Worker
45*6dbdd20aSAndroid Build Coastguard Worker #ifndef PR_GET_TAGGED_ADDR_CTRL
46*6dbdd20aSAndroid Build Coastguard Worker #define PR_GET_TAGGED_ADDR_CTRL 56
47*6dbdd20aSAndroid Build Coastguard Worker #endif
48*6dbdd20aSAndroid Build Coastguard Worker
49*6dbdd20aSAndroid Build Coastguard Worker #ifndef PR_TAGGED_ADDR_ENABLE
50*6dbdd20aSAndroid Build Coastguard Worker #define PR_TAGGED_ADDR_ENABLE (1UL << 0)
51*6dbdd20aSAndroid Build Coastguard Worker #endif
52*6dbdd20aSAndroid Build Coastguard Worker
53*6dbdd20aSAndroid Build Coastguard Worker #ifndef PR_MTE_TCF_SYNC
54*6dbdd20aSAndroid Build Coastguard Worker #define PR_MTE_TCF_SYNC (1UL << 1)
55*6dbdd20aSAndroid Build Coastguard Worker #endif
56*6dbdd20aSAndroid Build Coastguard Worker
57*6dbdd20aSAndroid Build Coastguard Worker #endif // OS_LINUX | OS_ANDROID
58*6dbdd20aSAndroid Build Coastguard Worker
59*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
60*6dbdd20aSAndroid Build Coastguard Worker #include <Windows.h>
61*6dbdd20aSAndroid Build Coastguard Worker #include <io.h>
62*6dbdd20aSAndroid Build Coastguard Worker #include <malloc.h> // For _aligned_malloc().
63*6dbdd20aSAndroid Build Coastguard Worker #endif
64*6dbdd20aSAndroid Build Coastguard Worker
65*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
66*6dbdd20aSAndroid Build Coastguard Worker #include <dlfcn.h>
67*6dbdd20aSAndroid Build Coastguard Worker #include <malloc.h>
68*6dbdd20aSAndroid Build Coastguard Worker
69*6dbdd20aSAndroid Build Coastguard Worker #ifdef M_PURGE
70*6dbdd20aSAndroid Build Coastguard Worker #define PERFETTO_M_PURGE M_PURGE
71*6dbdd20aSAndroid Build Coastguard Worker #else
72*6dbdd20aSAndroid Build Coastguard Worker // Only available in in-tree builds and on newer SDKs.
73*6dbdd20aSAndroid Build Coastguard Worker #define PERFETTO_M_PURGE -101
74*6dbdd20aSAndroid Build Coastguard Worker #endif // M_PURGE
75*6dbdd20aSAndroid Build Coastguard Worker
76*6dbdd20aSAndroid Build Coastguard Worker #ifdef M_PURGE_ALL
77*6dbdd20aSAndroid Build Coastguard Worker #define PERFETTO_M_PURGE_ALL M_PURGE_ALL
78*6dbdd20aSAndroid Build Coastguard Worker #else
79*6dbdd20aSAndroid Build Coastguard Worker // Only available in in-tree builds and on newer SDKs.
80*6dbdd20aSAndroid Build Coastguard Worker #define PERFETTO_M_PURGE_ALL -104
81*6dbdd20aSAndroid Build Coastguard Worker #endif // M_PURGE
82*6dbdd20aSAndroid Build Coastguard Worker
83*6dbdd20aSAndroid Build Coastguard Worker namespace {
84*6dbdd20aSAndroid Build Coastguard Worker extern "C" {
85*6dbdd20aSAndroid Build Coastguard Worker using MalloptType = int (*)(int, int);
86*6dbdd20aSAndroid Build Coastguard Worker }
87*6dbdd20aSAndroid Build Coastguard Worker } // namespace
88*6dbdd20aSAndroid Build Coastguard Worker #endif // OS_ANDROID
89*6dbdd20aSAndroid Build Coastguard Worker
90*6dbdd20aSAndroid Build Coastguard Worker namespace {
91*6dbdd20aSAndroid Build Coastguard Worker
92*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_X64_CPU_OPT)
93*6dbdd20aSAndroid Build Coastguard Worker
94*6dbdd20aSAndroid Build Coastguard Worker // Preserve the %rbx register via %rdi to work around a clang bug
95*6dbdd20aSAndroid Build Coastguard Worker // https://bugs.llvm.org/show_bug.cgi?id=17907 (%rbx in an output constraint
96*6dbdd20aSAndroid Build Coastguard Worker // is not considered a clobbered register).
97*6dbdd20aSAndroid Build Coastguard Worker #define PERFETTO_GETCPUID(a, b, c, d, a_inp, c_inp) \
98*6dbdd20aSAndroid Build Coastguard Worker asm("mov %%rbx, %%rdi\n" \
99*6dbdd20aSAndroid Build Coastguard Worker "cpuid\n" \
100*6dbdd20aSAndroid Build Coastguard Worker "xchg %%rdi, %%rbx\n" \
101*6dbdd20aSAndroid Build Coastguard Worker : "=a"(a), "=D"(b), "=c"(c), "=d"(d) \
102*6dbdd20aSAndroid Build Coastguard Worker : "a"(a_inp), "2"(c_inp))
103*6dbdd20aSAndroid Build Coastguard Worker
GetXCR0EAX()104*6dbdd20aSAndroid Build Coastguard Worker uint32_t GetXCR0EAX() {
105*6dbdd20aSAndroid Build Coastguard Worker uint32_t eax = 0, edx = 0;
106*6dbdd20aSAndroid Build Coastguard Worker asm("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
107*6dbdd20aSAndroid Build Coastguard Worker return eax;
108*6dbdd20aSAndroid Build Coastguard Worker }
109*6dbdd20aSAndroid Build Coastguard Worker
110*6dbdd20aSAndroid Build Coastguard Worker // If we are building with -msse4 check that the CPU actually supports it.
111*6dbdd20aSAndroid Build Coastguard Worker // This file must be kept in sync with gn/standalone/BUILD.gn.
112*6dbdd20aSAndroid Build Coastguard Worker void PERFETTO_EXPORT_COMPONENT __attribute__((constructor))
CheckCpuOptimizations()113*6dbdd20aSAndroid Build Coastguard Worker CheckCpuOptimizations() {
114*6dbdd20aSAndroid Build Coastguard Worker uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
115*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_GETCPUID(eax, ebx, ecx, edx, 1, 0);
116*6dbdd20aSAndroid Build Coastguard Worker
117*6dbdd20aSAndroid Build Coastguard Worker static constexpr uint64_t xcr0_xmm_mask = 0x2;
118*6dbdd20aSAndroid Build Coastguard Worker static constexpr uint64_t xcr0_ymm_mask = 0x4;
119*6dbdd20aSAndroid Build Coastguard Worker static constexpr uint64_t xcr0_avx_mask = xcr0_xmm_mask | xcr0_ymm_mask;
120*6dbdd20aSAndroid Build Coastguard Worker
121*6dbdd20aSAndroid Build Coastguard Worker const bool have_popcnt = ecx & (1u << 23);
122*6dbdd20aSAndroid Build Coastguard Worker const bool have_sse4_2 = ecx & (1u << 20);
123*6dbdd20aSAndroid Build Coastguard Worker const bool have_avx =
124*6dbdd20aSAndroid Build Coastguard Worker // Does the OS save/restore XMM and YMM state?
125*6dbdd20aSAndroid Build Coastguard Worker (ecx & (1u << 27)) && // OS support XGETBV.
126*6dbdd20aSAndroid Build Coastguard Worker (ecx & (1u << 28)) && // AVX supported in hardware
127*6dbdd20aSAndroid Build Coastguard Worker ((GetXCR0EAX() & xcr0_avx_mask) == xcr0_avx_mask);
128*6dbdd20aSAndroid Build Coastguard Worker
129*6dbdd20aSAndroid Build Coastguard Worker // Get level 7 features (eax = 7 and ecx= 0), to check for AVX2 support.
130*6dbdd20aSAndroid Build Coastguard Worker // (See Intel 64 and IA-32 Architectures Software Developer's Manual
131*6dbdd20aSAndroid Build Coastguard Worker // Volume 2A: Instruction Set Reference, A-M CPUID).
132*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_GETCPUID(eax, ebx, ecx, edx, 7, 0);
133*6dbdd20aSAndroid Build Coastguard Worker const bool have_avx2 = have_avx && ((ebx >> 5) & 0x1);
134*6dbdd20aSAndroid Build Coastguard Worker const bool have_bmi = (ebx >> 3) & 0x1;
135*6dbdd20aSAndroid Build Coastguard Worker const bool have_bmi2 = (ebx >> 8) & 0x1;
136*6dbdd20aSAndroid Build Coastguard Worker
137*6dbdd20aSAndroid Build Coastguard Worker if (!have_sse4_2 || !have_popcnt || !have_avx2 || !have_bmi || !have_bmi2) {
138*6dbdd20aSAndroid Build Coastguard Worker fprintf(
139*6dbdd20aSAndroid Build Coastguard Worker stderr,
140*6dbdd20aSAndroid Build Coastguard Worker "This executable requires a x86_64 cpu that supports SSE4.2, BMI2 and "
141*6dbdd20aSAndroid Build Coastguard Worker "AVX2.\n"
142*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
143*6dbdd20aSAndroid Build Coastguard Worker "On MacOS, this might be caused by running x86_64 binaries on arm64.\n"
144*6dbdd20aSAndroid Build Coastguard Worker "See https://github.com/google/perfetto/issues/294 for more.\n"
145*6dbdd20aSAndroid Build Coastguard Worker #endif
146*6dbdd20aSAndroid Build Coastguard Worker "Rebuild with enable_perfetto_x64_cpu_opt=false.\n");
147*6dbdd20aSAndroid Build Coastguard Worker _exit(126);
148*6dbdd20aSAndroid Build Coastguard Worker }
149*6dbdd20aSAndroid Build Coastguard Worker }
150*6dbdd20aSAndroid Build Coastguard Worker #endif
151*6dbdd20aSAndroid Build Coastguard Worker
152*6dbdd20aSAndroid Build Coastguard Worker } // namespace
153*6dbdd20aSAndroid Build Coastguard Worker
154*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
155*6dbdd20aSAndroid Build Coastguard Worker namespace base {
156*6dbdd20aSAndroid Build Coastguard Worker
157*6dbdd20aSAndroid Build Coastguard Worker namespace internal {
158*6dbdd20aSAndroid Build Coastguard Worker
159*6dbdd20aSAndroid Build Coastguard Worker std::atomic<uint32_t> g_cached_page_size{0};
160*6dbdd20aSAndroid Build Coastguard Worker
GetSysPageSizeSlowpath()161*6dbdd20aSAndroid Build Coastguard Worker uint32_t GetSysPageSizeSlowpath() {
162*6dbdd20aSAndroid Build Coastguard Worker uint32_t page_size = 0;
163*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
164*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
165*6dbdd20aSAndroid Build Coastguard Worker const int page_size_int = getpagesize();
166*6dbdd20aSAndroid Build Coastguard Worker // If sysconf() fails for obscure reasons (e.g. SELinux denial) assume the
167*6dbdd20aSAndroid Build Coastguard Worker // page size is 4KB. This is to avoid regressing subtle SDK usages, as old
168*6dbdd20aSAndroid Build Coastguard Worker // versions of this code had a static constant baked in.
169*6dbdd20aSAndroid Build Coastguard Worker page_size = static_cast<uint32_t>(page_size_int > 0 ? page_size_int : 4096);
170*6dbdd20aSAndroid Build Coastguard Worker #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
171*6dbdd20aSAndroid Build Coastguard Worker page_size = static_cast<uint32_t>(vm_page_size);
172*6dbdd20aSAndroid Build Coastguard Worker #else
173*6dbdd20aSAndroid Build Coastguard Worker page_size = 4096;
174*6dbdd20aSAndroid Build Coastguard Worker #endif
175*6dbdd20aSAndroid Build Coastguard Worker
176*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(page_size > 0 && page_size % 4096 == 0);
177*6dbdd20aSAndroid Build Coastguard Worker
178*6dbdd20aSAndroid Build Coastguard Worker // Races here are fine because any thread will write the same value.
179*6dbdd20aSAndroid Build Coastguard Worker g_cached_page_size.store(page_size, std::memory_order_relaxed);
180*6dbdd20aSAndroid Build Coastguard Worker return page_size;
181*6dbdd20aSAndroid Build Coastguard Worker }
182*6dbdd20aSAndroid Build Coastguard Worker
183*6dbdd20aSAndroid Build Coastguard Worker } // namespace internal
184*6dbdd20aSAndroid Build Coastguard Worker
MaybeReleaseAllocatorMemToOS()185*6dbdd20aSAndroid Build Coastguard Worker void MaybeReleaseAllocatorMemToOS() {
186*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
187*6dbdd20aSAndroid Build Coastguard Worker // mallopt() on Android requires SDK level 26. Many targets and embedders
188*6dbdd20aSAndroid Build Coastguard Worker // still depend on a lower SDK level. Given mallopt() is a quite simple API,
189*6dbdd20aSAndroid Build Coastguard Worker // use reflection to do this rather than bumping the SDK level for all
190*6dbdd20aSAndroid Build Coastguard Worker // embedders. This keeps the behavior of standalone builds aligned with
191*6dbdd20aSAndroid Build Coastguard Worker // in-tree builds.
192*6dbdd20aSAndroid Build Coastguard Worker static MalloptType mallopt_fn =
193*6dbdd20aSAndroid Build Coastguard Worker reinterpret_cast<MalloptType>(dlsym(RTLD_DEFAULT, "mallopt"));
194*6dbdd20aSAndroid Build Coastguard Worker if (!mallopt_fn)
195*6dbdd20aSAndroid Build Coastguard Worker return;
196*6dbdd20aSAndroid Build Coastguard Worker if (mallopt_fn(PERFETTO_M_PURGE_ALL, 0) == 0) {
197*6dbdd20aSAndroid Build Coastguard Worker mallopt_fn(PERFETTO_M_PURGE, 0);
198*6dbdd20aSAndroid Build Coastguard Worker }
199*6dbdd20aSAndroid Build Coastguard Worker #endif
200*6dbdd20aSAndroid Build Coastguard Worker }
201*6dbdd20aSAndroid Build Coastguard Worker
GetCurrentUserId()202*6dbdd20aSAndroid Build Coastguard Worker uid_t GetCurrentUserId() {
203*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
204*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
205*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
206*6dbdd20aSAndroid Build Coastguard Worker return geteuid();
207*6dbdd20aSAndroid Build Coastguard Worker #else
208*6dbdd20aSAndroid Build Coastguard Worker // TODO(primiano): On Windows we could hash the current user SID and derive a
209*6dbdd20aSAndroid Build Coastguard Worker // numeric user id [1]. It is not clear whether we need that. Right now that
210*6dbdd20aSAndroid Build Coastguard Worker // would not bring any benefit. Returning 0 unil we can prove we need it.
211*6dbdd20aSAndroid Build Coastguard Worker // [1]:https://android-review.googlesource.com/c/platform/external/perfetto/+/1513879/25/src/base/utils.cc
212*6dbdd20aSAndroid Build Coastguard Worker return 0;
213*6dbdd20aSAndroid Build Coastguard Worker #endif
214*6dbdd20aSAndroid Build Coastguard Worker }
215*6dbdd20aSAndroid Build Coastguard Worker
SetEnv(const std::string & key,const std::string & value)216*6dbdd20aSAndroid Build Coastguard Worker void SetEnv(const std::string& key, const std::string& value) {
217*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
218*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(::_putenv_s(key.c_str(), value.c_str()) == 0);
219*6dbdd20aSAndroid Build Coastguard Worker #else
220*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(::setenv(key.c_str(), value.c_str(), /*overwrite=*/true) == 0);
221*6dbdd20aSAndroid Build Coastguard Worker #endif
222*6dbdd20aSAndroid Build Coastguard Worker }
223*6dbdd20aSAndroid Build Coastguard Worker
UnsetEnv(const std::string & key)224*6dbdd20aSAndroid Build Coastguard Worker void UnsetEnv(const std::string& key) {
225*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
226*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(::_putenv_s(key.c_str(), "") == 0);
227*6dbdd20aSAndroid Build Coastguard Worker #else
228*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(::unsetenv(key.c_str()) == 0);
229*6dbdd20aSAndroid Build Coastguard Worker #endif
230*6dbdd20aSAndroid Build Coastguard Worker }
231*6dbdd20aSAndroid Build Coastguard Worker
Daemonize(std::function<int ()> parent_cb)232*6dbdd20aSAndroid Build Coastguard Worker void Daemonize(std::function<int()> parent_cb) {
233*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
234*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
235*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
236*6dbdd20aSAndroid Build Coastguard Worker Pipe pipe = Pipe::Create(Pipe::kBothBlock);
237*6dbdd20aSAndroid Build Coastguard Worker pid_t pid;
238*6dbdd20aSAndroid Build Coastguard Worker switch (pid = fork()) {
239*6dbdd20aSAndroid Build Coastguard Worker case -1:
240*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_FATAL("fork");
241*6dbdd20aSAndroid Build Coastguard Worker case 0: {
242*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(setsid() != -1);
243*6dbdd20aSAndroid Build Coastguard Worker base::ignore_result(chdir("/"));
244*6dbdd20aSAndroid Build Coastguard Worker base::ScopedFile null = base::OpenFile("/dev/null", O_RDONLY);
245*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(null);
246*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(dup2(*null, STDIN_FILENO) != -1);
247*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(dup2(*null, STDOUT_FILENO) != -1);
248*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(dup2(*null, STDERR_FILENO) != -1);
249*6dbdd20aSAndroid Build Coastguard Worker // Do not accidentally close stdin/stdout/stderr.
250*6dbdd20aSAndroid Build Coastguard Worker if (*null <= 2)
251*6dbdd20aSAndroid Build Coastguard Worker null.release();
252*6dbdd20aSAndroid Build Coastguard Worker WriteAll(*pipe.wr, "1", 1);
253*6dbdd20aSAndroid Build Coastguard Worker break;
254*6dbdd20aSAndroid Build Coastguard Worker }
255*6dbdd20aSAndroid Build Coastguard Worker default: {
256*6dbdd20aSAndroid Build Coastguard Worker // Wait for the child process to have reached the setsid() call. This is
257*6dbdd20aSAndroid Build Coastguard Worker // to avoid that 'adb shell perfetto -D' destroys the terminal (hence
258*6dbdd20aSAndroid Build Coastguard Worker // sending a SIGHUP to the child) before the child has detached from the
259*6dbdd20aSAndroid Build Coastguard Worker // terminal (see b/238644870).
260*6dbdd20aSAndroid Build Coastguard Worker
261*6dbdd20aSAndroid Build Coastguard Worker // This is to unblock the read() below (with EOF, which will fail the
262*6dbdd20aSAndroid Build Coastguard Worker // CHECK) in the unlikely case of the child crashing before WriteAll("1").
263*6dbdd20aSAndroid Build Coastguard Worker pipe.wr.reset();
264*6dbdd20aSAndroid Build Coastguard Worker char one = '\0';
265*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(Read(*pipe.rd, &one, sizeof(one)) == 1 && one == '1');
266*6dbdd20aSAndroid Build Coastguard Worker printf("%d\n", pid);
267*6dbdd20aSAndroid Build Coastguard Worker int err = parent_cb();
268*6dbdd20aSAndroid Build Coastguard Worker exit(err);
269*6dbdd20aSAndroid Build Coastguard Worker }
270*6dbdd20aSAndroid Build Coastguard Worker }
271*6dbdd20aSAndroid Build Coastguard Worker #else
272*6dbdd20aSAndroid Build Coastguard Worker // Avoid -Wunreachable warnings.
273*6dbdd20aSAndroid Build Coastguard Worker if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
274*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
275*6dbdd20aSAndroid Build Coastguard Worker ignore_result(parent_cb);
276*6dbdd20aSAndroid Build Coastguard Worker #endif // OS_WIN
277*6dbdd20aSAndroid Build Coastguard Worker }
278*6dbdd20aSAndroid Build Coastguard Worker
GetCurExecutablePath()279*6dbdd20aSAndroid Build Coastguard Worker std::string GetCurExecutablePath() {
280*6dbdd20aSAndroid Build Coastguard Worker std::string self_path;
281*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
282*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
283*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
284*6dbdd20aSAndroid Build Coastguard Worker char buf[PATH_MAX];
285*6dbdd20aSAndroid Build Coastguard Worker ssize_t size = readlink("/proc/self/exe", buf, sizeof(buf));
286*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(size != -1);
287*6dbdd20aSAndroid Build Coastguard Worker // readlink does not null terminate.
288*6dbdd20aSAndroid Build Coastguard Worker self_path = std::string(buf, static_cast<size_t>(size));
289*6dbdd20aSAndroid Build Coastguard Worker #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
290*6dbdd20aSAndroid Build Coastguard Worker uint32_t size = 0;
291*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(_NSGetExecutablePath(nullptr, &size));
292*6dbdd20aSAndroid Build Coastguard Worker self_path.resize(size);
293*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(_NSGetExecutablePath(&self_path[0], &size) == 0);
294*6dbdd20aSAndroid Build Coastguard Worker #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
295*6dbdd20aSAndroid Build Coastguard Worker char buf[MAX_PATH];
296*6dbdd20aSAndroid Build Coastguard Worker auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
297*6dbdd20aSAndroid Build Coastguard Worker self_path = std::string(buf, len);
298*6dbdd20aSAndroid Build Coastguard Worker #else
299*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_FATAL(
300*6dbdd20aSAndroid Build Coastguard Worker "GetCurExecutableDir() not implemented on the current platform");
301*6dbdd20aSAndroid Build Coastguard Worker #endif
302*6dbdd20aSAndroid Build Coastguard Worker return self_path;
303*6dbdd20aSAndroid Build Coastguard Worker }
304*6dbdd20aSAndroid Build Coastguard Worker
GetCurExecutableDir()305*6dbdd20aSAndroid Build Coastguard Worker std::string GetCurExecutableDir() {
306*6dbdd20aSAndroid Build Coastguard Worker auto path = GetCurExecutablePath();
307*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
308*6dbdd20aSAndroid Build Coastguard Worker // Paths in Windows can have both kinds of slashes (mingw vs msvc).
309*6dbdd20aSAndroid Build Coastguard Worker path = path.substr(0, path.find_last_of('\\'));
310*6dbdd20aSAndroid Build Coastguard Worker #endif
311*6dbdd20aSAndroid Build Coastguard Worker path = path.substr(0, path.find_last_of('/'));
312*6dbdd20aSAndroid Build Coastguard Worker return path;
313*6dbdd20aSAndroid Build Coastguard Worker }
314*6dbdd20aSAndroid Build Coastguard Worker
AlignedAlloc(size_t alignment,size_t size)315*6dbdd20aSAndroid Build Coastguard Worker void* AlignedAlloc(size_t alignment, size_t size) {
316*6dbdd20aSAndroid Build Coastguard Worker void* res = nullptr;
317*6dbdd20aSAndroid Build Coastguard Worker alignment = AlignUp<sizeof(void*)>(alignment); // At least pointer size.
318*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
319*6dbdd20aSAndroid Build Coastguard Worker // Window's _aligned_malloc() has a nearly identically signature to Unix's
320*6dbdd20aSAndroid Build Coastguard Worker // aligned_alloc() but its arguments are obviously swapped.
321*6dbdd20aSAndroid Build Coastguard Worker res = _aligned_malloc(size, alignment);
322*6dbdd20aSAndroid Build Coastguard Worker #else
323*6dbdd20aSAndroid Build Coastguard Worker // aligned_alloc() has been introduced in Android only in API 28.
324*6dbdd20aSAndroid Build Coastguard Worker // Also NaCl and Fuchsia seems to have only posix_memalign().
325*6dbdd20aSAndroid Build Coastguard Worker ignore_result(posix_memalign(&res, alignment, size));
326*6dbdd20aSAndroid Build Coastguard Worker #endif
327*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_CHECK(res);
328*6dbdd20aSAndroid Build Coastguard Worker return res;
329*6dbdd20aSAndroid Build Coastguard Worker }
330*6dbdd20aSAndroid Build Coastguard Worker
AlignedFree(void * ptr)331*6dbdd20aSAndroid Build Coastguard Worker void AlignedFree(void* ptr) {
332*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
333*6dbdd20aSAndroid Build Coastguard Worker _aligned_free(ptr); // MSDN says it is fine to pass nullptr.
334*6dbdd20aSAndroid Build Coastguard Worker #else
335*6dbdd20aSAndroid Build Coastguard Worker free(ptr);
336*6dbdd20aSAndroid Build Coastguard Worker #endif
337*6dbdd20aSAndroid Build Coastguard Worker }
338*6dbdd20aSAndroid Build Coastguard Worker
IsSyncMemoryTaggingEnabled()339*6dbdd20aSAndroid Build Coastguard Worker bool IsSyncMemoryTaggingEnabled() {
340*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
341*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
342*6dbdd20aSAndroid Build Coastguard Worker // Compute only once per lifetime of the process.
343*6dbdd20aSAndroid Build Coastguard Worker static bool cached_value = [] {
344*6dbdd20aSAndroid Build Coastguard Worker const int res = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
345*6dbdd20aSAndroid Build Coastguard Worker if (res < 0)
346*6dbdd20aSAndroid Build Coastguard Worker return false;
347*6dbdd20aSAndroid Build Coastguard Worker const uint32_t actl = static_cast<uint32_t>(res);
348*6dbdd20aSAndroid Build Coastguard Worker return (actl & PR_TAGGED_ADDR_ENABLE) && (actl & PR_MTE_TCF_SYNC);
349*6dbdd20aSAndroid Build Coastguard Worker }();
350*6dbdd20aSAndroid Build Coastguard Worker return cached_value;
351*6dbdd20aSAndroid Build Coastguard Worker #else
352*6dbdd20aSAndroid Build Coastguard Worker return false;
353*6dbdd20aSAndroid Build Coastguard Worker #endif
354*6dbdd20aSAndroid Build Coastguard Worker }
355*6dbdd20aSAndroid Build Coastguard Worker
HexDump(const void * data_void,size_t len,size_t bytes_per_line)356*6dbdd20aSAndroid Build Coastguard Worker std::string HexDump(const void* data_void, size_t len, size_t bytes_per_line) {
357*6dbdd20aSAndroid Build Coastguard Worker const char* data = reinterpret_cast<const char*>(data_void);
358*6dbdd20aSAndroid Build Coastguard Worker std::string res;
359*6dbdd20aSAndroid Build Coastguard Worker static const size_t kPadding = bytes_per_line * 3 + 12;
360*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<char[]> line(new char[bytes_per_line * 4 + 128]);
361*6dbdd20aSAndroid Build Coastguard Worker for (size_t i = 0; i < len; i += bytes_per_line) {
362*6dbdd20aSAndroid Build Coastguard Worker char* wptr = line.get();
363*6dbdd20aSAndroid Build Coastguard Worker wptr += base::SprintfTrunc(wptr, 19, "%08zX: ", i);
364*6dbdd20aSAndroid Build Coastguard Worker for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
365*6dbdd20aSAndroid Build Coastguard Worker wptr += base::SprintfTrunc(wptr, 4, "%02X ",
366*6dbdd20aSAndroid Build Coastguard Worker static_cast<unsigned>(data[j]) & 0xFF);
367*6dbdd20aSAndroid Build Coastguard Worker }
368*6dbdd20aSAndroid Build Coastguard Worker for (size_t j = static_cast<size_t>(wptr - line.get()); j < kPadding; ++j)
369*6dbdd20aSAndroid Build Coastguard Worker *(wptr++) = ' ';
370*6dbdd20aSAndroid Build Coastguard Worker for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
371*6dbdd20aSAndroid Build Coastguard Worker char c = data[j];
372*6dbdd20aSAndroid Build Coastguard Worker *(wptr++) = (c >= 32 && c < 127) ? c : '.';
373*6dbdd20aSAndroid Build Coastguard Worker }
374*6dbdd20aSAndroid Build Coastguard Worker *(wptr++) = '\n';
375*6dbdd20aSAndroid Build Coastguard Worker *(wptr++) = '\0';
376*6dbdd20aSAndroid Build Coastguard Worker res.append(line.get());
377*6dbdd20aSAndroid Build Coastguard Worker }
378*6dbdd20aSAndroid Build Coastguard Worker return res;
379*6dbdd20aSAndroid Build Coastguard Worker }
380*6dbdd20aSAndroid Build Coastguard Worker
381*6dbdd20aSAndroid Build Coastguard Worker } // namespace base
382*6dbdd20aSAndroid Build Coastguard Worker } // namespace perfetto
383