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