• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef SRC_PERFETTO_CMD_PERFETTO_CMD_H_
18 #define SRC_PERFETTO_CMD_PERFETTO_CMD_H_
19 
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include <time.h>
25 
26 #include "perfetto/base/build_config.h"
27 #include "perfetto/ext/base/event_fd.h"
28 #include "perfetto/ext/base/optional.h"
29 #include "perfetto/ext/base/pipe.h"
30 #include "perfetto/ext/base/scoped_file.h"
31 #include "perfetto/ext/base/unix_task_runner.h"
32 #include "perfetto/ext/tracing/core/consumer.h"
33 #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
34 #include "src/android_stats/perfetto_atoms.h"
35 #include "src/perfetto_cmd/rate_limiter.h"
36 
37 namespace perfetto {
38 
39 class PacketWriter;
40 class RateLimiter;
41 
42 // Directory for local state and temporary files. This is automatically
43 // created by the system by setting setprop persist.traced.enable=1.
44 extern const char* kStateDir;
45 
46 class PerfettoCmd : public Consumer {
47  public:
48   PerfettoCmd();
49   ~PerfettoCmd() override;
50 
51   // The main() is split in two stages: cmdline parsing and actual interaction
52   // with traced. This is to allow tools like tracebox to avoid spawning the
53   // service for no reason if the cmdline parsing fails.
54   // Return value:
55   //   nullopt: no error, the caller should call
56   //   ConnectToServiceRunAndMaybeNotify.
57   //   0-N: the caller should exit() with the given exit code.
58   base::Optional<int> ParseCmdlineAndMaybeDaemonize(int argc, char** argv);
59   int ConnectToServiceRunAndMaybeNotify();
60 
61   // perfetto::Consumer implementation.
62   void OnConnect() override;
63   void OnDisconnect() override;
64   void OnTracingDisabled(const std::string& error) override;
65   void OnTraceData(std::vector<TracePacket>, bool has_more) override;
66   void OnDetach(bool) override;
67   void OnAttach(bool, const TraceConfig&) override;
68   void OnTraceStats(bool, const TraceStats&) override;
69   void OnObservableEvents(const ObservableEvents&) override;
70 
SignalCtrlC()71   void SignalCtrlC() { ctrl_c_evt_.Notify(); }
72 
73  private:
74   bool OpenOutputFile();
75   void SetupCtrlCSignalHandler();
76   void FinalizeTraceAndExit();
77   void PrintUsage(const char* argv0);
78   void PrintServiceState(bool success, const TracingServiceState&);
79   void OnTimeout();
is_detach()80   bool is_detach() const { return !detach_key_.empty(); }
is_attach()81   bool is_attach() const { return !attach_key_.empty(); }
82 
83   // Once we call ReadBuffers we expect one or more calls to OnTraceData
84   // with the last call having |has_more| set to false. However we should
85   // gracefully handle the service failing to ever call OnTraceData or
86   // setting |has_more| incorrectly. To do this we maintain a timeout
87   // which finalizes and exits the client if we don't receive OnTraceData
88   // within OnTraceDataTimeoutMs of when we expected to.
89   void CheckTraceDataTimeout();
90 
91   int ConnectToServiceAndRun();
92 
93   enum BgProcessStatus : char {
94     kBackgroundOk = 0,
95     kBackgroundOtherError = 1,
96     kBackgroundTimeout = 2,
97   };
98 
99   // Used to implement the --background-wait flag.
100   //
101   // Waits (up to 30s) for the child process to signal (success or an error).
102   //
103   // Returns the status received from the child process or kTimeout, in case of
104   // timeout.
105   BgProcessStatus WaitOnBgProcessPipe();
106 
107   // Used to implement the --background-wait flag.
108   //
109   // Signals the parent process (if there is one) that it can exit (successfully
110   // or with an error).
111   //
112   // Only the first time this function is called is significant. Further calls
113   // will have no effect.
114   void NotifyBgProcessPipe(BgProcessStatus status);
115 
116 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
117   static base::ScopedFile CreateUnlinkedTmpFile();
118   void SaveTraceIntoIncidentOrCrash();
119   void SaveOutputToIncidentTraceOrCrash();
120   void ReportTraceToAndroidFrameworkOrCrash();
121 #endif
122   void LogUploadEvent(PerfettoStatsdAtom atom);
123   void LogTriggerEvents(PerfettoTriggerAtom atom,
124                         const std::vector<std::string>& trigger_names);
125 
126   base::UnixTaskRunner task_runner_;
127 
128   std::unique_ptr<RateLimiter> limiter_;
129   std::unique_ptr<perfetto::TracingService::ConsumerEndpoint>
130       consumer_endpoint_;
131   std::unique_ptr<TraceConfig> trace_config_;
132   std::unique_ptr<PacketWriter> packet_writer_;
133   base::ScopedFstream trace_out_stream_;
134   std::vector<std::string> triggers_to_activate_;
135   std::string trace_out_path_;
136   base::EventFd ctrl_c_evt_;
137   base::Pipe background_wait_pipe_;
138   bool save_to_incidentd_ = false;
139   bool report_to_android_framework_ = false;
140   bool statsd_logging_ = false;
141   bool update_guardrail_state_ = false;
142   uint64_t bytes_written_ = 0;
143   std::string detach_key_;
144   std::string attach_key_;
145   bool stop_trace_once_attached_ = false;
146   bool redetach_once_attached_ = false;
147   bool query_service_ = false;
148   bool query_service_output_raw_ = false;
149   bool bugreport_ = false;
150   bool background_ = false;
151   bool background_wait_ = false;
152   bool ignore_guardrails_ = false;
153   bool upload_flag_ = false;
154   std::string uuid_;
155 
156   // How long we expect to trace for or 0 if the trace is indefinite.
157   uint32_t expected_duration_ms_ = 0;
158   bool trace_data_timeout_armed_ = false;
159 };
160 
161 }  // namespace perfetto
162 
163 #endif  // SRC_PERFETTO_CMD_PERFETTO_CMD_H_
164