1*6dbdd20aSAndroid Build Coastguard Worker /* 2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2018 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 #ifndef SRC_PERFETTO_CMD_PERFETTO_CMD_H_ 18*6dbdd20aSAndroid Build Coastguard Worker #define SRC_PERFETTO_CMD_PERFETTO_CMD_H_ 19*6dbdd20aSAndroid Build Coastguard Worker 20*6dbdd20aSAndroid Build Coastguard Worker #include <cstdint> 21*6dbdd20aSAndroid Build Coastguard Worker #include <functional> 22*6dbdd20aSAndroid Build Coastguard Worker #include <list> 23*6dbdd20aSAndroid Build Coastguard Worker #include <memory> 24*6dbdd20aSAndroid Build Coastguard Worker #include <optional> 25*6dbdd20aSAndroid Build Coastguard Worker #include <string> 26*6dbdd20aSAndroid Build Coastguard Worker #include <vector> 27*6dbdd20aSAndroid Build Coastguard Worker 28*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/build_config.h" 29*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/event_fd.h" 30*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/pipe.h" 31*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/scoped_file.h" 32*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/thread_task_runner.h" 33*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/unix_task_runner.h" 34*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/uuid.h" 35*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/weak_ptr.h" 36*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/tracing/core/basic_types.h" 37*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/tracing/core/consumer.h" 38*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h" 39*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/core/forward_decls.h" 40*6dbdd20aSAndroid Build Coastguard Worker #include "src/android_stats/perfetto_atoms.h" 41*6dbdd20aSAndroid Build Coastguard Worker #include "src/perfetto_cmd/packet_writer.h" 42*6dbdd20aSAndroid Build Coastguard Worker 43*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto { 44*6dbdd20aSAndroid Build Coastguard Worker 45*6dbdd20aSAndroid Build Coastguard Worker // Directory for local state and temporary files. This is automatically 46*6dbdd20aSAndroid Build Coastguard Worker // created by the system by setting setprop persist.traced.enable=1. 47*6dbdd20aSAndroid Build Coastguard Worker extern const char* kStateDir; 48*6dbdd20aSAndroid Build Coastguard Worker 49*6dbdd20aSAndroid Build Coastguard Worker class PerfettoCmd : public Consumer { 50*6dbdd20aSAndroid Build Coastguard Worker public: 51*6dbdd20aSAndroid Build Coastguard Worker PerfettoCmd(); 52*6dbdd20aSAndroid Build Coastguard Worker ~PerfettoCmd() override; 53*6dbdd20aSAndroid Build Coastguard Worker 54*6dbdd20aSAndroid Build Coastguard Worker // The main() is split in two stages: cmdline parsing and actual interaction 55*6dbdd20aSAndroid Build Coastguard Worker // with traced. This is to allow tools like tracebox to avoid spawning the 56*6dbdd20aSAndroid Build Coastguard Worker // service for no reason if the cmdline parsing fails. 57*6dbdd20aSAndroid Build Coastguard Worker // Return value: 58*6dbdd20aSAndroid Build Coastguard Worker // std::nullopt: no error, the caller should call 59*6dbdd20aSAndroid Build Coastguard Worker // ConnectToServiceRunAndMaybeNotify. 60*6dbdd20aSAndroid Build Coastguard Worker // 0-N: the caller should exit() with the given exit code. 61*6dbdd20aSAndroid Build Coastguard Worker std::optional<int> ParseCmdlineAndMaybeDaemonize(int argc, char** argv); 62*6dbdd20aSAndroid Build Coastguard Worker int ConnectToServiceRunAndMaybeNotify(); 63*6dbdd20aSAndroid Build Coastguard Worker 64*6dbdd20aSAndroid Build Coastguard Worker // perfetto::Consumer implementation. 65*6dbdd20aSAndroid Build Coastguard Worker void OnConnect() override; 66*6dbdd20aSAndroid Build Coastguard Worker void OnDisconnect() override; 67*6dbdd20aSAndroid Build Coastguard Worker void OnTracingDisabled(const std::string& error) override; 68*6dbdd20aSAndroid Build Coastguard Worker void OnTraceData(std::vector<TracePacket>, bool has_more) override; 69*6dbdd20aSAndroid Build Coastguard Worker void OnDetach(bool) override; 70*6dbdd20aSAndroid Build Coastguard Worker void OnAttach(bool, const TraceConfig&) override; 71*6dbdd20aSAndroid Build Coastguard Worker void OnTraceStats(bool, const TraceStats&) override; 72*6dbdd20aSAndroid Build Coastguard Worker void OnObservableEvents(const ObservableEvents&) override; 73*6dbdd20aSAndroid Build Coastguard Worker void OnSessionCloned(const OnSessionClonedArgs&) override; 74*6dbdd20aSAndroid Build Coastguard Worker SignalCtrlC()75*6dbdd20aSAndroid Build Coastguard Worker void SignalCtrlC() { ctrl_c_evt_.Notify(); } 76*6dbdd20aSAndroid Build Coastguard Worker 77*6dbdd20aSAndroid Build Coastguard Worker private: 78*6dbdd20aSAndroid Build Coastguard Worker struct SnapshotTriggerInfo; 79*6dbdd20aSAndroid Build Coastguard Worker 80*6dbdd20aSAndroid Build Coastguard Worker enum CloneThreadMode { kSingleExtraThread, kNewThreadPerRequest }; 81*6dbdd20aSAndroid Build Coastguard Worker 82*6dbdd20aSAndroid Build Coastguard Worker bool OpenOutputFile(); 83*6dbdd20aSAndroid Build Coastguard Worker void SetupCtrlCSignalHandler(); 84*6dbdd20aSAndroid Build Coastguard Worker void FinalizeTraceAndExit(); 85*6dbdd20aSAndroid Build Coastguard Worker void PrintUsage(const char* argv0); 86*6dbdd20aSAndroid Build Coastguard Worker void PrintServiceState(bool success, const TracingServiceState&); 87*6dbdd20aSAndroid Build Coastguard Worker void CloneAllBugreportTraces(bool success, const TracingServiceState&); 88*6dbdd20aSAndroid Build Coastguard Worker 89*6dbdd20aSAndroid Build Coastguard Worker void CloneSessionOnThread(TracingSessionID, 90*6dbdd20aSAndroid Build Coastguard Worker const std::string& cmdline, // \0 separated. 91*6dbdd20aSAndroid Build Coastguard Worker CloneThreadMode, 92*6dbdd20aSAndroid Build Coastguard Worker const std::optional<SnapshotTriggerInfo>& trigger, 93*6dbdd20aSAndroid Build Coastguard Worker std::function<void()> on_clone_callback); 94*6dbdd20aSAndroid Build Coastguard Worker void OnTimeout(); is_detach()95*6dbdd20aSAndroid Build Coastguard Worker bool is_detach() const { return !detach_key_.empty(); } is_attach()96*6dbdd20aSAndroid Build Coastguard Worker bool is_attach() const { return !attach_key_.empty(); } is_clone()97*6dbdd20aSAndroid Build Coastguard Worker bool is_clone() const { 98*6dbdd20aSAndroid Build Coastguard Worker return clone_tsid_.has_value() || !clone_name_.empty(); 99*6dbdd20aSAndroid Build Coastguard Worker } 100*6dbdd20aSAndroid Build Coastguard Worker 101*6dbdd20aSAndroid Build Coastguard Worker // Once we call ReadBuffers we expect one or more calls to OnTraceData 102*6dbdd20aSAndroid Build Coastguard Worker // with the last call having |has_more| set to false. However we should 103*6dbdd20aSAndroid Build Coastguard Worker // gracefully handle the service failing to ever call OnTraceData or 104*6dbdd20aSAndroid Build Coastguard Worker // setting |has_more| incorrectly. To do this we maintain a timeout 105*6dbdd20aSAndroid Build Coastguard Worker // which finalizes and exits the client if we don't receive OnTraceData 106*6dbdd20aSAndroid Build Coastguard Worker // within OnTraceDataTimeoutMs of when we expected to. 107*6dbdd20aSAndroid Build Coastguard Worker void CheckTraceDataTimeout(); 108*6dbdd20aSAndroid Build Coastguard Worker 109*6dbdd20aSAndroid Build Coastguard Worker int ConnectToServiceAndRun(); 110*6dbdd20aSAndroid Build Coastguard Worker 111*6dbdd20aSAndroid Build Coastguard Worker void ReadbackTraceDataAndQuit(const std::string& error); 112*6dbdd20aSAndroid Build Coastguard Worker 113*6dbdd20aSAndroid Build Coastguard Worker enum BgProcessStatus : char { 114*6dbdd20aSAndroid Build Coastguard Worker kBackgroundOk = 0, 115*6dbdd20aSAndroid Build Coastguard Worker kBackgroundOtherError = 1, 116*6dbdd20aSAndroid Build Coastguard Worker kBackgroundTimeout = 2, 117*6dbdd20aSAndroid Build Coastguard Worker }; 118*6dbdd20aSAndroid Build Coastguard Worker 119*6dbdd20aSAndroid Build Coastguard Worker // Used to implement the --background-wait flag. 120*6dbdd20aSAndroid Build Coastguard Worker // 121*6dbdd20aSAndroid Build Coastguard Worker // Waits (up to 30s) for the child process to signal (success or an error). 122*6dbdd20aSAndroid Build Coastguard Worker // 123*6dbdd20aSAndroid Build Coastguard Worker // Returns the status received from the child process or kTimeout, in case of 124*6dbdd20aSAndroid Build Coastguard Worker // timeout. 125*6dbdd20aSAndroid Build Coastguard Worker BgProcessStatus WaitOnBgProcessPipe(); 126*6dbdd20aSAndroid Build Coastguard Worker 127*6dbdd20aSAndroid Build Coastguard Worker // Used to implement the --background-wait flag. 128*6dbdd20aSAndroid Build Coastguard Worker // 129*6dbdd20aSAndroid Build Coastguard Worker // Signals the parent process (if there is one) that it can exit (successfully 130*6dbdd20aSAndroid Build Coastguard Worker // or with an error). 131*6dbdd20aSAndroid Build Coastguard Worker // 132*6dbdd20aSAndroid Build Coastguard Worker // Only the first time this function is called is significant. Further calls 133*6dbdd20aSAndroid Build Coastguard Worker // will have no effect. 134*6dbdd20aSAndroid Build Coastguard Worker void NotifyBgProcessPipe(BgProcessStatus status); 135*6dbdd20aSAndroid Build Coastguard Worker 136*6dbdd20aSAndroid Build Coastguard Worker void OnCloneSnapshotTriggerReceived(TracingSessionID, 137*6dbdd20aSAndroid Build Coastguard Worker const SnapshotTriggerInfo& trigger); 138*6dbdd20aSAndroid Build Coastguard Worker 139*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) 140*6dbdd20aSAndroid Build Coastguard Worker static base::ScopedFile CreateUnlinkedTmpFile(); 141*6dbdd20aSAndroid Build Coastguard Worker void SaveTraceIntoIncidentOrCrash(); 142*6dbdd20aSAndroid Build Coastguard Worker void SaveOutputToIncidentTraceOrCrash(); 143*6dbdd20aSAndroid Build Coastguard Worker void ReportTraceToAndroidFrameworkOrCrash(); 144*6dbdd20aSAndroid Build Coastguard Worker #endif 145*6dbdd20aSAndroid Build Coastguard Worker void LogUploadEvent(PerfettoStatsdAtom atom); 146*6dbdd20aSAndroid Build Coastguard Worker void LogUploadEvent(PerfettoStatsdAtom atom, const std::string& trigger_name); 147*6dbdd20aSAndroid Build Coastguard Worker void LogTriggerEvents(PerfettoTriggerAtom atom, 148*6dbdd20aSAndroid Build Coastguard Worker const std::vector<std::string>& trigger_names); 149*6dbdd20aSAndroid Build Coastguard Worker 150*6dbdd20aSAndroid Build Coastguard Worker base::UnixTaskRunner task_runner_; 151*6dbdd20aSAndroid Build Coastguard Worker 152*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<perfetto::TracingService::ConsumerEndpoint> 153*6dbdd20aSAndroid Build Coastguard Worker consumer_endpoint_; 154*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<TraceConfig> trace_config_; 155*6dbdd20aSAndroid Build Coastguard Worker std::optional<PacketWriter> packet_writer_; 156*6dbdd20aSAndroid Build Coastguard Worker base::ScopedFstream trace_out_stream_; 157*6dbdd20aSAndroid Build Coastguard Worker std::vector<std::string> triggers_to_activate_; 158*6dbdd20aSAndroid Build Coastguard Worker std::string trace_out_path_; 159*6dbdd20aSAndroid Build Coastguard Worker base::EventFd ctrl_c_evt_; 160*6dbdd20aSAndroid Build Coastguard Worker bool ctrl_c_handler_installed_ = false; 161*6dbdd20aSAndroid Build Coastguard Worker base::Pipe background_wait_pipe_; 162*6dbdd20aSAndroid Build Coastguard Worker bool save_to_incidentd_ = false; 163*6dbdd20aSAndroid Build Coastguard Worker bool report_to_android_framework_ = false; 164*6dbdd20aSAndroid Build Coastguard Worker bool statsd_logging_ = false; 165*6dbdd20aSAndroid Build Coastguard Worker bool tracing_succeeded_ = false; 166*6dbdd20aSAndroid Build Coastguard Worker uint64_t bytes_written_ = 0; 167*6dbdd20aSAndroid Build Coastguard Worker std::string detach_key_; 168*6dbdd20aSAndroid Build Coastguard Worker std::string attach_key_; 169*6dbdd20aSAndroid Build Coastguard Worker bool stop_trace_once_attached_ = false; 170*6dbdd20aSAndroid Build Coastguard Worker bool redetach_once_attached_ = false; 171*6dbdd20aSAndroid Build Coastguard Worker bool query_service_ = false; 172*6dbdd20aSAndroid Build Coastguard Worker bool query_service_output_raw_ = false; 173*6dbdd20aSAndroid Build Coastguard Worker bool query_service_long_ = false; 174*6dbdd20aSAndroid Build Coastguard Worker bool clone_all_bugreport_traces_ = false; 175*6dbdd20aSAndroid Build Coastguard Worker bool bugreport_ = false; 176*6dbdd20aSAndroid Build Coastguard Worker bool background_ = false; 177*6dbdd20aSAndroid Build Coastguard Worker bool background_wait_ = false; 178*6dbdd20aSAndroid Build Coastguard Worker bool ignore_guardrails_ = false; 179*6dbdd20aSAndroid Build Coastguard Worker bool upload_flag_ = false; 180*6dbdd20aSAndroid Build Coastguard Worker bool connected_ = false; 181*6dbdd20aSAndroid Build Coastguard Worker std::string uuid_; 182*6dbdd20aSAndroid Build Coastguard Worker std::optional<TracingSessionID> clone_tsid_{}; 183*6dbdd20aSAndroid Build Coastguard Worker std::string clone_name_; 184*6dbdd20aSAndroid Build Coastguard Worker bool clone_for_bugreport_ = false; 185*6dbdd20aSAndroid Build Coastguard Worker std::function<void()> on_session_cloned_; 186*6dbdd20aSAndroid Build Coastguard Worker 187*6dbdd20aSAndroid Build Coastguard Worker // How long we expect to trace for or 0 if the trace is indefinite. 188*6dbdd20aSAndroid Build Coastguard Worker uint32_t expected_duration_ms_ = 0; 189*6dbdd20aSAndroid Build Coastguard Worker bool trace_data_timeout_armed_ = false; 190*6dbdd20aSAndroid Build Coastguard Worker 191*6dbdd20aSAndroid Build Coastguard Worker // The aux threads used to invoke secondary instances of PerfettoCmd to create 192*6dbdd20aSAndroid Build Coastguard Worker // snapshots. This is used only when the trace config involves a 193*6dbdd20aSAndroid Build Coastguard Worker // CLONE_SNAPSHOT trigger or when using --save-all-for-bugreport. 194*6dbdd20aSAndroid Build Coastguard Worker std::list<base::ThreadTaskRunner> snapshot_threads_; 195*6dbdd20aSAndroid Build Coastguard Worker int snapshot_count_ = 0; 196*6dbdd20aSAndroid Build Coastguard Worker std::string snapshot_config_; 197*6dbdd20aSAndroid Build Coastguard Worker // If the trigger caused the clone operation, we want to save the information 198*6dbdd20aSAndroid Build Coastguard Worker // about that trigger to the trace We may get multiple triggers with the same 199*6dbdd20aSAndroid Build Coastguard Worker // name, so we pass the entire structure to uniquely identify the trigger 200*6dbdd20aSAndroid Build Coastguard Worker // later. This structure is identical to the 201*6dbdd20aSAndroid Build Coastguard Worker // `TracingServiceImpl::TriggerInfo`. 202*6dbdd20aSAndroid Build Coastguard Worker struct SnapshotTriggerInfo { 203*6dbdd20aSAndroid Build Coastguard Worker uint64_t boot_time_ns = 0; 204*6dbdd20aSAndroid Build Coastguard Worker std::string trigger_name; 205*6dbdd20aSAndroid Build Coastguard Worker std::string producer_name; 206*6dbdd20aSAndroid Build Coastguard Worker uid_t producer_uid = 0; 207*6dbdd20aSAndroid Build Coastguard Worker }; 208*6dbdd20aSAndroid Build Coastguard Worker std::optional<SnapshotTriggerInfo> snapshot_trigger_info_; 209*6dbdd20aSAndroid Build Coastguard Worker 210*6dbdd20aSAndroid Build Coastguard Worker base::WeakPtrFactory<PerfettoCmd> weak_factory_{this}; 211*6dbdd20aSAndroid Build Coastguard Worker }; 212*6dbdd20aSAndroid Build Coastguard Worker 213*6dbdd20aSAndroid Build Coastguard Worker } // namespace perfetto 214*6dbdd20aSAndroid Build Coastguard Worker 215*6dbdd20aSAndroid Build Coastguard Worker #endif // SRC_PERFETTO_CMD_PERFETTO_CMD_H_ 216