xref: /aosp_15_r20/external/perfetto/src/tracebox/tracebox.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2021 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 <algorithm>
18*6dbdd20aSAndroid Build Coastguard Worker #include <cstdint>
19*6dbdd20aSAndroid Build Coastguard Worker #include <cstdio>
20*6dbdd20aSAndroid Build Coastguard Worker #include <cstdlib>
21*6dbdd20aSAndroid Build Coastguard Worker #include <cstring>
22*6dbdd20aSAndroid Build Coastguard Worker #include <string>
23*6dbdd20aSAndroid Build Coastguard Worker 
24*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/build_config.h"
25*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
26*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/proc_utils.h"
27*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/file_utils.h"
28*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/pipe.h"
29*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/subprocess.h"
30*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/utils.h"
31*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/traced/traced.h"
32*6dbdd20aSAndroid Build Coastguard Worker #include "src/perfetto_cmd/perfetto_cmd.h"
33*6dbdd20aSAndroid Build Coastguard Worker #include "src/websocket_bridge/websocket_bridge.h"
34*6dbdd20aSAndroid Build Coastguard Worker 
35*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_TRACED_PERF)
36*6dbdd20aSAndroid Build Coastguard Worker #include "src/profiling/perf/traced_perf.h"
37*6dbdd20aSAndroid Build Coastguard Worker #endif
38*6dbdd20aSAndroid Build Coastguard Worker 
39*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
40*6dbdd20aSAndroid Build Coastguard Worker namespace {
41*6dbdd20aSAndroid Build Coastguard Worker 
42*6dbdd20aSAndroid Build Coastguard Worker struct Applet {
43*6dbdd20aSAndroid Build Coastguard Worker   using MainFunction = int (*)(int /*argc*/, char** /*argv*/);
44*6dbdd20aSAndroid Build Coastguard Worker   const char* name;
45*6dbdd20aSAndroid Build Coastguard Worker   MainFunction entrypoint;
46*6dbdd20aSAndroid Build Coastguard Worker };
47*6dbdd20aSAndroid Build Coastguard Worker 
48*6dbdd20aSAndroid Build Coastguard Worker const Applet g_applets[]{
49*6dbdd20aSAndroid Build Coastguard Worker     {"traced", ServiceMain},
50*6dbdd20aSAndroid Build Coastguard Worker     {"traced_probes", ProbesMain},
51*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_TRACED_PERF)
52*6dbdd20aSAndroid Build Coastguard Worker     {"traced_perf", TracedPerfMain},
53*6dbdd20aSAndroid Build Coastguard Worker #endif
54*6dbdd20aSAndroid Build Coastguard Worker     {"perfetto", PerfettoCmdMain},
55*6dbdd20aSAndroid Build Coastguard Worker     {"trigger_perfetto", TriggerPerfettoMain},
56*6dbdd20aSAndroid Build Coastguard Worker     {"websocket_bridge", WebsocketBridgeMain},
57*6dbdd20aSAndroid Build Coastguard Worker };
58*6dbdd20aSAndroid Build Coastguard Worker 
PrintUsage()59*6dbdd20aSAndroid Build Coastguard Worker void PrintUsage() {
60*6dbdd20aSAndroid Build Coastguard Worker   printf(R"(Welcome to Perfetto tracing!
61*6dbdd20aSAndroid Build Coastguard Worker 
62*6dbdd20aSAndroid Build Coastguard Worker Tracebox is a bundle containing all the tracing services and the perfetto
63*6dbdd20aSAndroid Build Coastguard Worker cmdline client in one binary. It can be used either to spawn manually the
64*6dbdd20aSAndroid Build Coastguard Worker various subprocess or in "autostart" mode, which will take care of starting
65*6dbdd20aSAndroid Build Coastguard Worker and tearing down the services for you.
66*6dbdd20aSAndroid Build Coastguard Worker 
67*6dbdd20aSAndroid Build Coastguard Worker Usage in autostart mode:
68*6dbdd20aSAndroid Build Coastguard Worker   tracebox -t 10s -o trace_file.perfetto-trace sched/sched_switch
69*6dbdd20aSAndroid Build Coastguard Worker   See tracebox --help for more options.
70*6dbdd20aSAndroid Build Coastguard Worker 
71*6dbdd20aSAndroid Build Coastguard Worker Usage in manual mode:
72*6dbdd20aSAndroid Build Coastguard Worker   tracebox applet_name [args ...]  (e.g. ./tracebox traced --help)
73*6dbdd20aSAndroid Build Coastguard Worker   Applets:)");
74*6dbdd20aSAndroid Build Coastguard Worker 
75*6dbdd20aSAndroid Build Coastguard Worker   for (const Applet& applet : g_applets)
76*6dbdd20aSAndroid Build Coastguard Worker     printf(" %s", applet.name);
77*6dbdd20aSAndroid Build Coastguard Worker 
78*6dbdd20aSAndroid Build Coastguard Worker   printf(R"(
79*6dbdd20aSAndroid Build Coastguard Worker 
80*6dbdd20aSAndroid Build Coastguard Worker See also:
81*6dbdd20aSAndroid Build Coastguard Worker   * https://perfetto.dev/docs/
82*6dbdd20aSAndroid Build Coastguard Worker   * The config editor in the record page of https://ui.perfetto.dev/
83*6dbdd20aSAndroid Build Coastguard Worker )");
84*6dbdd20aSAndroid Build Coastguard Worker }
85*6dbdd20aSAndroid Build Coastguard Worker 
PrintTraceboxUsage()86*6dbdd20aSAndroid Build Coastguard Worker void PrintTraceboxUsage() {
87*6dbdd20aSAndroid Build Coastguard Worker   printf(R"(
88*6dbdd20aSAndroid Build Coastguard Worker Tracebox-specific args
89*6dbdd20aSAndroid Build Coastguard Worker   --system-sockets      : Forces the use of system-sockets when using autostart
90*6dbdd20aSAndroid Build Coastguard Worker                           mode. Cannot be used in applet mode.
91*6dbdd20aSAndroid Build Coastguard Worker )");
92*6dbdd20aSAndroid Build Coastguard Worker }
93*6dbdd20aSAndroid Build Coastguard Worker 
TraceboxMain(int argc,char ** argv)94*6dbdd20aSAndroid Build Coastguard Worker int TraceboxMain(int argc, char** argv) {
95*6dbdd20aSAndroid Build Coastguard Worker   // Manual mode: if either the 1st argument (argv[1]) or the exe name (argv[0])
96*6dbdd20aSAndroid Build Coastguard Worker   // match the name of an applet, directly invoke that without further
97*6dbdd20aSAndroid Build Coastguard Worker   // modifications.
98*6dbdd20aSAndroid Build Coastguard Worker 
99*6dbdd20aSAndroid Build Coastguard Worker   // Extract the file name from argv[0].
100*6dbdd20aSAndroid Build Coastguard Worker   char* slash = strrchr(argv[0], '/');
101*6dbdd20aSAndroid Build Coastguard Worker   char* argv0 = slash ? slash + 1 : argv[0];
102*6dbdd20aSAndroid Build Coastguard Worker 
103*6dbdd20aSAndroid Build Coastguard Worker   for (const Applet& applet : g_applets) {
104*6dbdd20aSAndroid Build Coastguard Worker     if (!strcmp(argv0, applet.name))
105*6dbdd20aSAndroid Build Coastguard Worker       return applet.entrypoint(argc, argv);
106*6dbdd20aSAndroid Build Coastguard Worker     if (argc > 1 && !strcmp(argv[1], applet.name))
107*6dbdd20aSAndroid Build Coastguard Worker       return applet.entrypoint(argc - 1, &argv[1]);
108*6dbdd20aSAndroid Build Coastguard Worker   }
109*6dbdd20aSAndroid Build Coastguard Worker 
110*6dbdd20aSAndroid Build Coastguard Worker   // If no matching applet is found, switch to the autostart mode. In this mode
111*6dbdd20aSAndroid Build Coastguard Worker   // we make tracebox behave like the cmdline client (without needing to prefix
112*6dbdd20aSAndroid Build Coastguard Worker   // it with "perfetto"), but will also start traced and traced_probes.
113*6dbdd20aSAndroid Build Coastguard Worker   // As part of this we also use a different namespace for the producer/consumer
114*6dbdd20aSAndroid Build Coastguard Worker   // sockets, to avoid clashing with the system daemon.
115*6dbdd20aSAndroid Build Coastguard Worker 
116*6dbdd20aSAndroid Build Coastguard Worker   if (argc <= 1) {
117*6dbdd20aSAndroid Build Coastguard Worker     PrintUsage();
118*6dbdd20aSAndroid Build Coastguard Worker     return 1;
119*6dbdd20aSAndroid Build Coastguard Worker   }
120*6dbdd20aSAndroid Build Coastguard Worker 
121*6dbdd20aSAndroid Build Coastguard Worker   auto* end = std::remove_if(argv, argv + argc, [](char* arg) {
122*6dbdd20aSAndroid Build Coastguard Worker     return !strcmp(arg, "--system-sockets");
123*6dbdd20aSAndroid Build Coastguard Worker   });
124*6dbdd20aSAndroid Build Coastguard Worker   if (end < (argv + argc - 1)) {
125*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_ELOG("Cannot specify --system-sockets multiple times");
126*6dbdd20aSAndroid Build Coastguard Worker     return 1;
127*6dbdd20aSAndroid Build Coastguard Worker   }
128*6dbdd20aSAndroid Build Coastguard Worker   if (bool system_sockets = end == (argv + argc - 1); system_sockets) {
129*6dbdd20aSAndroid Build Coastguard Worker     argc--;
130*6dbdd20aSAndroid Build Coastguard Worker   } else {
131*6dbdd20aSAndroid Build Coastguard Worker     auto pid_str = std::to_string(static_cast<uint64_t>(base::GetProcessId()));
132*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
133*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
134*6dbdd20aSAndroid Build Coastguard Worker     // Use an unlinked abstract domain socket on Linux/Android.
135*6dbdd20aSAndroid Build Coastguard Worker     std::string consumer_socket = "@traced-c-" + pid_str;
136*6dbdd20aSAndroid Build Coastguard Worker     std::string producer_socket = "@traced-p-" + pid_str;
137*6dbdd20aSAndroid Build Coastguard Worker #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
138*6dbdd20aSAndroid Build Coastguard Worker     std::string consumer_socket = "/tmp/traced-c-" + pid_str;
139*6dbdd20aSAndroid Build Coastguard Worker     std::string producer_socket = "/tmp/traced-p-" + pid_str;
140*6dbdd20aSAndroid Build Coastguard Worker #else
141*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_FATAL("The autostart mode is not supported on this platform");
142*6dbdd20aSAndroid Build Coastguard Worker #endif
143*6dbdd20aSAndroid Build Coastguard Worker 
144*6dbdd20aSAndroid Build Coastguard Worker     // If the caller has set the PERFETTO_*_SOCK_NAME, respect those.
145*6dbdd20aSAndroid Build Coastguard Worker     if (const char* env = getenv("PERFETTO_CONSUMER_SOCK_NAME"); env) {
146*6dbdd20aSAndroid Build Coastguard Worker       consumer_socket = env;
147*6dbdd20aSAndroid Build Coastguard Worker     }
148*6dbdd20aSAndroid Build Coastguard Worker     if (const char* env = getenv("PERFETTO_PRODUCER_SOCK_NAME"); env) {
149*6dbdd20aSAndroid Build Coastguard Worker       producer_socket = env;
150*6dbdd20aSAndroid Build Coastguard Worker     }
151*6dbdd20aSAndroid Build Coastguard Worker     base::SetEnv("PERFETTO_CONSUMER_SOCK_NAME", consumer_socket);
152*6dbdd20aSAndroid Build Coastguard Worker     base::SetEnv("PERFETTO_PRODUCER_SOCK_NAME", producer_socket);
153*6dbdd20aSAndroid Build Coastguard Worker   }
154*6dbdd20aSAndroid Build Coastguard Worker 
155*6dbdd20aSAndroid Build Coastguard Worker   PerfettoCmd perfetto_cmd;
156*6dbdd20aSAndroid Build Coastguard Worker 
157*6dbdd20aSAndroid Build Coastguard Worker   // If the cmdline parsing fails, stop here, no need to spawn services.
158*6dbdd20aSAndroid Build Coastguard Worker   // It will daemonize if --background. In that case the subprocesses will be
159*6dbdd20aSAndroid Build Coastguard Worker   // spawned by the damonized cmdline client, which is what we want so killing
160*6dbdd20aSAndroid Build Coastguard Worker   // the backgrounded cmdline client will also kill the other services, as they
161*6dbdd20aSAndroid Build Coastguard Worker   // will live in the same background session.
162*6dbdd20aSAndroid Build Coastguard Worker   auto opt_res = perfetto_cmd.ParseCmdlineAndMaybeDaemonize(argc, argv);
163*6dbdd20aSAndroid Build Coastguard Worker   if (opt_res.has_value()) {
164*6dbdd20aSAndroid Build Coastguard Worker     if (*opt_res != 0) {
165*6dbdd20aSAndroid Build Coastguard Worker       PrintTraceboxUsage();
166*6dbdd20aSAndroid Build Coastguard Worker     }
167*6dbdd20aSAndroid Build Coastguard Worker     return *opt_res;
168*6dbdd20aSAndroid Build Coastguard Worker   }
169*6dbdd20aSAndroid Build Coastguard Worker 
170*6dbdd20aSAndroid Build Coastguard Worker   std::string self_path = base::GetCurExecutablePath();
171*6dbdd20aSAndroid Build Coastguard Worker   base::Subprocess traced({self_path, "traced"});
172*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
173*6dbdd20aSAndroid Build Coastguard Worker   // |traced_sync_pipe| is used to synchronize with traced socket creation.
174*6dbdd20aSAndroid Build Coastguard Worker   // traced will write "1" and close the FD when the IPC socket is listening
175*6dbdd20aSAndroid Build Coastguard Worker   // (or traced crashed).
176*6dbdd20aSAndroid Build Coastguard Worker   base::Pipe traced_sync_pipe = base::Pipe::Create();
177*6dbdd20aSAndroid Build Coastguard Worker   int traced_fd = *traced_sync_pipe.wr;
178*6dbdd20aSAndroid Build Coastguard Worker   base::SetEnv("TRACED_NOTIFY_FD", std::to_string(traced_fd));
179*6dbdd20aSAndroid Build Coastguard Worker   traced.args.preserve_fds.emplace_back(traced_fd);
180*6dbdd20aSAndroid Build Coastguard Worker   // Create a new process group so CTRL-C is delivered only to the cmdline
181*6dbdd20aSAndroid Build Coastguard Worker   // process (the tracebox one) and not to traced. traced will still exit once
182*6dbdd20aSAndroid Build Coastguard Worker   // the main process exits, but this allows graceful stopping of the trace
183*6dbdd20aSAndroid Build Coastguard Worker   // without abruptedly killing traced{,probes} when hitting CTRL+C.
184*6dbdd20aSAndroid Build Coastguard Worker   traced.args.posix_proc_group_id = 0;  // 0 = start a new process group.
185*6dbdd20aSAndroid Build Coastguard Worker #endif
186*6dbdd20aSAndroid Build Coastguard Worker   traced.Start();
187*6dbdd20aSAndroid Build Coastguard Worker 
188*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
189*6dbdd20aSAndroid Build Coastguard Worker   traced_sync_pipe.wr.reset();
190*6dbdd20aSAndroid Build Coastguard Worker 
191*6dbdd20aSAndroid Build Coastguard Worker   std::string traced_notify_msg;
192*6dbdd20aSAndroid Build Coastguard Worker   base::ReadPlatformHandle(*traced_sync_pipe.rd, &traced_notify_msg);
193*6dbdd20aSAndroid Build Coastguard Worker   if (traced_notify_msg != "1")
194*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_FATAL("The tracing service failed unexpectedly. Check the logs");
195*6dbdd20aSAndroid Build Coastguard Worker #endif
196*6dbdd20aSAndroid Build Coastguard Worker 
197*6dbdd20aSAndroid Build Coastguard Worker   base::Subprocess traced_probes(
198*6dbdd20aSAndroid Build Coastguard Worker       {self_path, "traced_probes", "--reset-ftrace"});
199*6dbdd20aSAndroid Build Coastguard Worker   // Put traced_probes in the same process group as traced. Same reason (CTRL+C)
200*6dbdd20aSAndroid Build Coastguard Worker   // but it's not worth creating a new group.
201*6dbdd20aSAndroid Build Coastguard Worker   traced_probes.args.posix_proc_group_id = traced.pid();
202*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
203*6dbdd20aSAndroid Build Coastguard Worker   // |traced_probes_sync_pipe| is used to synchronize with traced socket
204*6dbdd20aSAndroid Build Coastguard Worker   // creation. traced will write "1" and close the FD when the IPC socket is
205*6dbdd20aSAndroid Build Coastguard Worker   // listening (or traced crashed).
206*6dbdd20aSAndroid Build Coastguard Worker   base::Pipe traced_probes_sync_pipe = base::Pipe::Create();
207*6dbdd20aSAndroid Build Coastguard Worker   int traced_probes_fd = *traced_probes_sync_pipe.wr;
208*6dbdd20aSAndroid Build Coastguard Worker   base::SetEnv("TRACED_PROBES_NOTIFY_FD", std::to_string(traced_probes_fd));
209*6dbdd20aSAndroid Build Coastguard Worker   traced_probes.args.preserve_fds.emplace_back(traced_probes_fd);
210*6dbdd20aSAndroid Build Coastguard Worker #endif
211*6dbdd20aSAndroid Build Coastguard Worker   traced_probes.Start();
212*6dbdd20aSAndroid Build Coastguard Worker 
213*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
214*6dbdd20aSAndroid Build Coastguard Worker   traced_probes_sync_pipe.wr.reset();
215*6dbdd20aSAndroid Build Coastguard Worker 
216*6dbdd20aSAndroid Build Coastguard Worker   std::string traced_probes_notify_msg;
217*6dbdd20aSAndroid Build Coastguard Worker   base::ReadPlatformHandle(*traced_probes_sync_pipe.rd,
218*6dbdd20aSAndroid Build Coastguard Worker                            &traced_probes_notify_msg);
219*6dbdd20aSAndroid Build Coastguard Worker   if (traced_probes_notify_msg != "1")
220*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_FATAL(
221*6dbdd20aSAndroid Build Coastguard Worker         "The traced_probes service failed unexpectedly. Check the logs");
222*6dbdd20aSAndroid Build Coastguard Worker #endif
223*6dbdd20aSAndroid Build Coastguard Worker 
224*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_TRACED_PERF)
225*6dbdd20aSAndroid Build Coastguard Worker   base::Subprocess traced_perf({self_path, "traced_perf"});
226*6dbdd20aSAndroid Build Coastguard Worker   // Put traced_perf in the same process group as traced. Same reason (CTRL+C)
227*6dbdd20aSAndroid Build Coastguard Worker   // but it's not worth creating a new group.
228*6dbdd20aSAndroid Build Coastguard Worker   traced_perf.args.posix_proc_group_id = traced.pid();
229*6dbdd20aSAndroid Build Coastguard Worker 
230*6dbdd20aSAndroid Build Coastguard Worker   base::Pipe traced_perf_sync_pipe = base::Pipe::Create();
231*6dbdd20aSAndroid Build Coastguard Worker   int traced_perf_fd = *traced_perf_sync_pipe.wr;
232*6dbdd20aSAndroid Build Coastguard Worker   base::SetEnv("TRACED_PERF_NOTIFY_FD", std::to_string(traced_perf_fd));
233*6dbdd20aSAndroid Build Coastguard Worker   traced_perf.args.preserve_fds.emplace_back(traced_perf_fd);
234*6dbdd20aSAndroid Build Coastguard Worker   traced_perf.Start();
235*6dbdd20aSAndroid Build Coastguard Worker   traced_perf_sync_pipe.wr.reset();
236*6dbdd20aSAndroid Build Coastguard Worker 
237*6dbdd20aSAndroid Build Coastguard Worker   std::string traced_perf_notify_msg;
238*6dbdd20aSAndroid Build Coastguard Worker   base::ReadPlatformHandle(*traced_perf_sync_pipe.rd, &traced_perf_notify_msg);
239*6dbdd20aSAndroid Build Coastguard Worker   if (traced_perf_notify_msg != "1")
240*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_FATAL(
241*6dbdd20aSAndroid Build Coastguard Worker         "The traced_perf service failed unexpectedly. Check the logs");
242*6dbdd20aSAndroid Build Coastguard Worker #endif
243*6dbdd20aSAndroid Build Coastguard Worker 
244*6dbdd20aSAndroid Build Coastguard Worker   perfetto_cmd.ConnectToServiceRunAndMaybeNotify();
245*6dbdd20aSAndroid Build Coastguard Worker   return 0;
246*6dbdd20aSAndroid Build Coastguard Worker }
247*6dbdd20aSAndroid Build Coastguard Worker 
248*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
249*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
250*6dbdd20aSAndroid Build Coastguard Worker 
main(int argc,char ** argv)251*6dbdd20aSAndroid Build Coastguard Worker int main(int argc, char** argv) {
252*6dbdd20aSAndroid Build Coastguard Worker   return perfetto::TraceboxMain(argc, argv);
253*6dbdd20aSAndroid Build Coastguard Worker }
254