1 /* 2 * Copyright (C) 2017 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_TRACING_CORE_TRACING_SERVICE_IMPL_H_ 18 #define SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_ 19 20 #include <algorithm> 21 #include <functional> 22 #include <map> 23 #include <memory> 24 #include <mutex> 25 #include <random> 26 #include <set> 27 #include <utility> 28 #include <vector> 29 30 #include "perfetto/base/logging.h" 31 #include "perfetto/base/status.h" 32 #include "perfetto/base/time.h" 33 #include "perfetto/ext/base/circular_queue.h" 34 #include "perfetto/ext/base/optional.h" 35 #include "perfetto/ext/base/periodic_task.h" 36 #include "perfetto/ext/base/weak_ptr.h" 37 #include "perfetto/ext/tracing/core/basic_types.h" 38 #include "perfetto/ext/tracing/core/commit_data_request.h" 39 #include "perfetto/ext/tracing/core/observable_events.h" 40 #include "perfetto/ext/tracing/core/shared_memory_abi.h" 41 #include "perfetto/ext/tracing/core/trace_stats.h" 42 #include "perfetto/ext/tracing/core/tracing_service.h" 43 #include "perfetto/tracing/core/data_source_config.h" 44 #include "perfetto/tracing/core/data_source_descriptor.h" 45 #include "perfetto/tracing/core/forward_decls.h" 46 #include "perfetto/tracing/core/trace_config.h" 47 #include "src/android_stats/perfetto_atoms.h" 48 #include "src/tracing/core/id_allocator.h" 49 50 namespace protozero { 51 class MessageFilter; 52 } 53 54 namespace perfetto { 55 56 namespace base { 57 class TaskRunner; 58 } // namespace base 59 60 namespace protos { 61 namespace gen { 62 enum TraceStats_FinalFlushOutcome : int; 63 } 64 } // namespace protos 65 66 class Consumer; 67 class Producer; 68 class SharedMemory; 69 class SharedMemoryArbiterImpl; 70 class TraceBuffer; 71 class TracePacket; 72 73 // The tracing service business logic. 74 class TracingServiceImpl : public TracingService { 75 private: 76 struct DataSourceInstance; 77 78 public: 79 static constexpr size_t kDefaultShmPageSize = 4096ul; 80 static constexpr size_t kDefaultShmSize = 256 * 1024ul; 81 static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul; 82 static constexpr uint32_t kDataSourceStopTimeoutMs = 5000; 83 static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d, 84 0x42, 0xba, 0x81, 0xdc, 0x33, 0x32, 85 0x6d, 0x57, 0xa0, 0x79}; 86 static constexpr size_t kMaxTracePacketSliceSize = 87 128 * 1024 - 512; // This is ipc::kIPCBufferSize - 512, see assertion in 88 // tracing_integration_test.cc and b/195065199 89 90 // This is a rough threshold to determine how many bytes to read from the 91 // buffers on each iteration when writing into a file. Since filtering 92 // allocates memory, this limits the amount of memory allocated. 93 static constexpr size_t kWriteIntoFileChunkSize = 1024 * 1024ul; 94 95 // The implementation behind the service endpoint exposed to each producer. 96 class ProducerEndpointImpl : public TracingService::ProducerEndpoint { 97 public: 98 ProducerEndpointImpl(ProducerID, 99 uid_t uid, 100 pid_t pid, 101 TracingServiceImpl*, 102 base::TaskRunner*, 103 Producer*, 104 const std::string& producer_name, 105 const std::string& sdk_version, 106 bool in_process, 107 bool smb_scraping_enabled); 108 ~ProducerEndpointImpl() override; 109 110 // TracingService::ProducerEndpoint implementation. 111 void RegisterDataSource(const DataSourceDescriptor&) override; 112 void UpdateDataSource(const DataSourceDescriptor&) override; 113 void UnregisterDataSource(const std::string& name) override; 114 void RegisterTraceWriter(uint32_t writer_id, 115 uint32_t target_buffer) override; 116 void UnregisterTraceWriter(uint32_t writer_id) override; 117 void CommitData(const CommitDataRequest&, CommitDataCallback) override; 118 void SetupSharedMemory(std::unique_ptr<SharedMemory>, 119 size_t page_size_bytes, 120 bool provided_by_producer); 121 std::unique_ptr<TraceWriter> CreateTraceWriter( 122 BufferID, 123 BufferExhaustedPolicy) override; 124 SharedMemoryArbiter* MaybeSharedMemoryArbiter() override; 125 bool IsShmemProvidedByProducer() const override; 126 void NotifyFlushComplete(FlushRequestID) override; 127 void NotifyDataSourceStarted(DataSourceInstanceID) override; 128 void NotifyDataSourceStopped(DataSourceInstanceID) override; 129 SharedMemory* shared_memory() const override; 130 size_t shared_buffer_page_size_kb() const override; 131 void ActivateTriggers(const std::vector<std::string>&) override; 132 void Sync(std::function<void()> callback) override; 133 134 void OnTracingSetup(); 135 void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&); 136 void StartDataSource(DataSourceInstanceID, const DataSourceConfig&); 137 void StopDataSource(DataSourceInstanceID); 138 void Flush(FlushRequestID, const std::vector<DataSourceInstanceID>&); 139 void OnFreeBuffers(const std::vector<BufferID>& target_buffers); 140 void ClearIncrementalState(const std::vector<DataSourceInstanceID>&); 141 is_allowed_target_buffer(BufferID buffer_id)142 bool is_allowed_target_buffer(BufferID buffer_id) const { 143 return allowed_target_buffers_.count(buffer_id); 144 } 145 buffer_id_for_writer(WriterID writer_id)146 base::Optional<BufferID> buffer_id_for_writer(WriterID writer_id) const { 147 const auto it = writers_.find(writer_id); 148 if (it != writers_.end()) 149 return it->second; 150 return base::nullopt; 151 } 152 uid()153 uid_t uid() const { return uid_; } pid()154 pid_t pid() const { return pid_; } 155 156 private: 157 friend class TracingServiceImpl; 158 friend class TracingServiceImplTest; 159 friend class TracingIntegrationTest; 160 ProducerEndpointImpl(const ProducerEndpointImpl&) = delete; 161 ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete; 162 163 ProducerID const id_; 164 const uid_t uid_; 165 const pid_t pid_; 166 TracingServiceImpl* const service_; 167 base::TaskRunner* const task_runner_; 168 Producer* producer_; 169 std::unique_ptr<SharedMemory> shared_memory_; 170 size_t shared_buffer_page_size_kb_ = 0; 171 SharedMemoryABI shmem_abi_; 172 size_t shmem_size_hint_bytes_ = 0; 173 size_t shmem_page_size_hint_bytes_ = 0; 174 bool is_shmem_provided_by_producer_ = false; 175 const std::string name_; 176 std::string sdk_version_; 177 bool in_process_; 178 bool smb_scraping_enabled_; 179 180 // Set of the global target_buffer IDs that the producer is configured to 181 // write into in any active tracing session. 182 std::set<BufferID> allowed_target_buffers_; 183 184 // Maps registered TraceWriter IDs to their target buffers as registered by 185 // the producer. Note that producers aren't required to register their 186 // writers, so we may see commits of chunks with WriterIDs that aren't 187 // contained in this map. However, if a producer does register a writer, the 188 // service will prevent the writer from writing into any other buffer than 189 // the one associated with it here. The BufferIDs stored in this map are 190 // untrusted, so need to be verified against |allowed_target_buffers_| 191 // before use. 192 std::map<WriterID, BufferID> writers_; 193 194 // This is used only in in-process configurations. 195 // SharedMemoryArbiterImpl methods themselves are thread-safe. 196 std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_; 197 198 PERFETTO_THREAD_CHECKER(thread_checker_) 199 base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_; // Keep last. 200 }; 201 202 // The implementation behind the service endpoint exposed to each consumer. 203 class ConsumerEndpointImpl : public TracingService::ConsumerEndpoint { 204 public: 205 ConsumerEndpointImpl(TracingServiceImpl*, 206 base::TaskRunner*, 207 Consumer*, 208 uid_t uid); 209 ~ConsumerEndpointImpl() override; 210 211 void NotifyOnTracingDisabled(const std::string& error); 212 213 // TracingService::ConsumerEndpoint implementation. 214 void EnableTracing(const TraceConfig&, base::ScopedFile) override; 215 void ChangeTraceConfig(const TraceConfig& cfg) override; 216 void StartTracing() override; 217 void DisableTracing() override; 218 void ReadBuffers() override; 219 void FreeBuffers() override; 220 void Flush(uint32_t timeout_ms, FlushCallback) override; 221 void Detach(const std::string& key) override; 222 void Attach(const std::string& key) override; 223 void GetTraceStats() override; 224 void ObserveEvents(uint32_t enabled_event_types) override; 225 void QueryServiceState(QueryServiceStateCallback) override; 226 void QueryCapabilities(QueryCapabilitiesCallback) override; 227 void SaveTraceForBugreport(SaveTraceForBugreportCallback) override; 228 229 // Will queue a task to notify the consumer about the state change. 230 void OnDataSourceInstanceStateChange(const ProducerEndpointImpl&, 231 const DataSourceInstance&); 232 void OnAllDataSourcesStarted(); 233 234 private: 235 friend class TracingServiceImpl; 236 ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete; 237 ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete; 238 239 // Returns a pointer to an ObservableEvents object that the caller can fill 240 // and schedules a task to send the ObservableEvents to the consumer. 241 ObservableEvents* AddObservableEvents(); 242 243 base::TaskRunner* const task_runner_; 244 TracingServiceImpl* const service_; 245 Consumer* const consumer_; 246 uid_t const uid_; 247 TracingSessionID tracing_session_id_ = 0; 248 249 // Whether the consumer is interested in DataSourceInstance state change 250 // events. 251 uint32_t observable_events_mask_ = 0; 252 253 // ObservableEvents that will be sent to the consumer. If set, a task to 254 // flush the events to the consumer has been queued. 255 std::unique_ptr<ObservableEvents> observable_events_; 256 257 PERFETTO_THREAD_CHECKER(thread_checker_) 258 base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_; // Keep last. 259 }; 260 261 explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>, 262 base::TaskRunner*); 263 ~TracingServiceImpl() override; 264 265 // Called by ProducerEndpointImpl. 266 void DisconnectProducer(ProducerID); 267 void RegisterDataSource(ProducerID, const DataSourceDescriptor&); 268 void UpdateDataSource(ProducerID, const DataSourceDescriptor&); 269 void UnregisterDataSource(ProducerID, const std::string& name); 270 void CopyProducerPageIntoLogBuffer(ProducerID, 271 uid_t, 272 pid_t, 273 WriterID, 274 ChunkID, 275 BufferID, 276 uint16_t num_fragments, 277 uint8_t chunk_flags, 278 bool chunk_complete, 279 const uint8_t* src, 280 size_t size); 281 void ApplyChunkPatches(ProducerID, 282 const std::vector<CommitDataRequest::ChunkToPatch>&); 283 void NotifyFlushDoneForProducer(ProducerID, FlushRequestID); 284 void NotifyDataSourceStarted(ProducerID, const DataSourceInstanceID); 285 void NotifyDataSourceStopped(ProducerID, const DataSourceInstanceID); 286 void ActivateTriggers(ProducerID, const std::vector<std::string>& triggers); 287 288 // Called by ConsumerEndpointImpl. 289 bool DetachConsumer(ConsumerEndpointImpl*, const std::string& key); 290 bool AttachConsumer(ConsumerEndpointImpl*, const std::string& key); 291 void DisconnectConsumer(ConsumerEndpointImpl*); 292 base::Status EnableTracing(ConsumerEndpointImpl*, 293 const TraceConfig&, 294 base::ScopedFile); 295 void ChangeTraceConfig(ConsumerEndpointImpl*, const TraceConfig&); 296 297 base::Status StartTracing(TracingSessionID); 298 void DisableTracing(TracingSessionID, bool disable_immediately = false); 299 void Flush(TracingSessionID tsid, 300 uint32_t timeout_ms, 301 ConsumerEndpoint::FlushCallback); 302 void FlushAndDisableTracing(TracingSessionID); 303 304 // Starts reading the internal tracing buffers from the tracing session `tsid` 305 // and sends them to `*consumer` (which must be != nullptr). 306 // 307 // Only reads a limited amount of data in one call. If there's more data, 308 // immediately schedules itself on a PostTask. 309 // 310 // Returns false in case of error. 311 bool ReadBuffersIntoConsumer(TracingSessionID tsid, 312 ConsumerEndpointImpl* consumer); 313 314 // Reads all the tracing buffers from the tracing session `tsid` and writes 315 // them into the associated file. 316 // 317 // Reads all the data in the buffers (or until the file is full) before 318 // returning. 319 // 320 // If the tracing session write_period_ms is 0, the file is full or there has 321 // been an error, flushes the file and closes it. Otherwise, schedules itself 322 // to be executed after write_period_ms. 323 // 324 // Returns false in case of error. 325 bool ReadBuffersIntoFile(TracingSessionID); 326 327 void FreeBuffers(TracingSessionID); 328 329 // Service implementation. 330 std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer( 331 Producer*, 332 uid_t uid, 333 pid_t pid, 334 const std::string& producer_name, 335 size_t shared_memory_size_hint_bytes = 0, 336 bool in_process = false, 337 ProducerSMBScrapingMode smb_scraping_mode = 338 ProducerSMBScrapingMode::kDefault, 339 size_t shared_memory_page_size_hint_bytes = 0, 340 std::unique_ptr<SharedMemory> shm = nullptr, 341 const std::string& sdk_version = {}) override; 342 343 std::unique_ptr<TracingService::ConsumerEndpoint> ConnectConsumer( 344 Consumer*, 345 uid_t) override; 346 347 // Set whether SMB scraping should be enabled by default or not. Producers can 348 // override this setting for their own SMBs. SetSMBScrapingEnabled(bool enabled)349 void SetSMBScrapingEnabled(bool enabled) override { 350 smb_scraping_enabled_ = enabled; 351 } 352 353 // Exposed mainly for testing. num_producers()354 size_t num_producers() const { return producers_.size(); } 355 ProducerEndpointImpl* GetProducer(ProducerID) const; 356 357 private: 358 friend class TracingServiceImplTest; 359 friend class TracingIntegrationTest; 360 361 static constexpr int64_t kOneDayInNs = 24ll * 60 * 60 * 1000 * 1000 * 1000; 362 363 struct TriggerHistory { 364 int64_t timestamp_ns; 365 uint64_t name_hash; 366 367 bool operator<(const TriggerHistory& other) const { 368 return timestamp_ns < other.timestamp_ns; 369 } 370 }; 371 372 struct RegisteredDataSource { 373 ProducerID producer_id; 374 DataSourceDescriptor descriptor; 375 }; 376 377 // Represents an active data source for a tracing session. 378 struct DataSourceInstance { DataSourceInstanceDataSourceInstance379 DataSourceInstance(DataSourceInstanceID id, 380 const DataSourceConfig& cfg, 381 const std::string& ds_name, 382 bool notify_on_start, 383 bool notify_on_stop, 384 bool handles_incremental_state_invalidation) 385 : instance_id(id), 386 config(cfg), 387 data_source_name(ds_name), 388 will_notify_on_start(notify_on_start), 389 will_notify_on_stop(notify_on_stop), 390 handles_incremental_state_clear( 391 handles_incremental_state_invalidation) {} 392 DataSourceInstance(const DataSourceInstance&) = delete; 393 DataSourceInstance& operator=(const DataSourceInstance&) = delete; 394 395 DataSourceInstanceID instance_id; 396 DataSourceConfig config; 397 std::string data_source_name; 398 bool will_notify_on_start; 399 bool will_notify_on_stop; 400 bool handles_incremental_state_clear; 401 402 enum DataSourceInstanceState { 403 CONFIGURED, 404 STARTING, 405 STARTED, 406 STOPPING, 407 STOPPED 408 }; 409 DataSourceInstanceState state = CONFIGURED; 410 }; 411 412 struct PendingFlush { 413 std::set<ProducerID> producers; 414 ConsumerEndpoint::FlushCallback callback; PendingFlushPendingFlush415 explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {} 416 }; 417 418 // Holds the state of a tracing session. A tracing session is uniquely bound 419 // a specific Consumer. Each Consumer can own one or more sessions. 420 struct TracingSession { 421 enum State { 422 DISABLED = 0, 423 CONFIGURED, 424 STARTED, 425 DISABLING_WAITING_STOP_ACKS 426 }; 427 428 TracingSession(TracingSessionID, 429 ConsumerEndpointImpl*, 430 const TraceConfig&, 431 base::TaskRunner*); 432 TracingSession(TracingSession&&) = delete; 433 TracingSession& operator=(TracingSession&&) = delete; 434 num_buffersTracingSession435 size_t num_buffers() const { return buffers_index.size(); } 436 delay_to_next_write_period_msTracingSession437 uint32_t delay_to_next_write_period_ms() const { 438 PERFETTO_DCHECK(write_period_ms > 0); 439 return write_period_ms - 440 static_cast<uint32_t>(base::GetWallTimeMs().count() % 441 write_period_ms); 442 } 443 flush_timeout_msTracingSession444 uint32_t flush_timeout_ms() { 445 uint32_t timeout_ms = config.flush_timeout_ms(); 446 return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs; 447 } 448 data_source_stop_timeout_msTracingSession449 uint32_t data_source_stop_timeout_ms() { 450 uint32_t timeout_ms = config.data_source_stop_timeout_ms(); 451 return timeout_ms ? timeout_ms : kDataSourceStopTimeoutMs; 452 } 453 GetPacketSequenceIDTracingSession454 PacketSequenceID GetPacketSequenceID(ProducerID producer_id, 455 WriterID writer_id) { 456 auto key = std::make_pair(producer_id, writer_id); 457 auto it = packet_sequence_ids.find(key); 458 if (it != packet_sequence_ids.end()) 459 return it->second; 460 // We shouldn't run out of sequence IDs (producer ID is 16 bit, writer IDs 461 // are limited to 1024). 462 static_assert(kMaxPacketSequenceID > kMaxProducerID * kMaxWriterID, 463 "PacketSequenceID value space doesn't cover service " 464 "sequence ID and all producer/writer ID combinations!"); 465 PERFETTO_DCHECK(last_packet_sequence_id < kMaxPacketSequenceID); 466 PacketSequenceID sequence_id = ++last_packet_sequence_id; 467 packet_sequence_ids[key] = sequence_id; 468 return sequence_id; 469 } 470 GetDataSourceInstanceTracingSession471 DataSourceInstance* GetDataSourceInstance( 472 ProducerID producer_id, 473 DataSourceInstanceID instance_id) { 474 for (auto& inst_kv : data_source_instances) { 475 if (inst_kv.first != producer_id || 476 inst_kv.second.instance_id != instance_id) { 477 continue; 478 } 479 return &inst_kv.second; 480 } 481 return nullptr; 482 } 483 AllDataSourceInstancesStartedTracingSession484 bool AllDataSourceInstancesStarted() { 485 return std::all_of( 486 data_source_instances.begin(), data_source_instances.end(), 487 [](decltype(data_source_instances)::const_reference x) { 488 return x.second.state == DataSourceInstance::STARTED; 489 }); 490 } 491 AllDataSourceInstancesStoppedTracingSession492 bool AllDataSourceInstancesStopped() { 493 return std::all_of( 494 data_source_instances.begin(), data_source_instances.end(), 495 [](decltype(data_source_instances)::const_reference x) { 496 return x.second.state == DataSourceInstance::STOPPED; 497 }); 498 } 499 500 const TracingSessionID id; 501 502 // The consumer that started the session. 503 // Can be nullptr if the consumer detached from the session. 504 ConsumerEndpointImpl* consumer_maybe_null; 505 506 // Unix uid of the consumer. This is valid even after the consumer detaches 507 // and does not change for the entire duration of the session. It is used to 508 // prevent that a consumer re-attaches to a session from a different uid. 509 uid_t const consumer_uid; 510 511 // The list of triggers this session received while alive and the time they 512 // were received at. This is used to insert 'fake' packets back to the 513 // consumer so they can tell when some event happened. The order matches the 514 // order they were received. 515 struct TriggerInfo { 516 uint64_t boot_time_ns; 517 std::string trigger_name; 518 std::string producer_name; 519 uid_t producer_uid; 520 }; 521 std::vector<TriggerInfo> received_triggers; 522 523 // The trace config provided by the Consumer when calling 524 // EnableTracing(), plus any updates performed by ChangeTraceConfig. 525 TraceConfig config; 526 527 // List of data source instances that have been enabled on the various 528 // producers for this tracing session. 529 // TODO(rsavitski): at the time of writing, the map structure is unused 530 // (even when the calling code has a key). This is also an opportunity to 531 // consider an alternative data type, e.g. a map of vectors. 532 std::multimap<ProducerID, DataSourceInstance> data_source_instances; 533 534 // For each Flush(N) request, keeps track of the set of producers for which 535 // we are still awaiting a NotifyFlushComplete(N) ack. 536 std::map<FlushRequestID, PendingFlush> pending_flushes; 537 538 // Maps a per-trace-session buffer index into the corresponding global 539 // BufferID (shared namespace amongst all consumers). This vector has as 540 // many entries as |config.buffers_size()|. 541 std::vector<BufferID> buffers_index; 542 543 std::map<std::pair<ProducerID, WriterID>, PacketSequenceID> 544 packet_sequence_ids; 545 PacketSequenceID last_packet_sequence_id = kServicePacketSequenceID; 546 547 // Whether we should emit the trace stats next time we reach EOF while 548 // performing ReadBuffers. 549 bool should_emit_stats = false; 550 551 // Whether we should emit the sync marker the next time ReadBuffers() is 552 // called. 553 bool should_emit_sync_marker = false; 554 555 // Whether we mirrored the trace config back to the trace output yet. 556 bool did_emit_config = false; 557 558 // Whether we put the system info into the trace output yet. 559 bool did_emit_system_info = false; 560 561 // The number of received triggers we've emitted into the trace output. 562 size_t num_triggers_emitted_into_trace = 0; 563 564 // Packets that failed validation of the TrustedPacket. 565 uint64_t invalid_packets = 0; 566 567 // Flush() stats. See comments in trace_stats.proto for more. 568 uint64_t flushes_requested = 0; 569 uint64_t flushes_succeeded = 0; 570 uint64_t flushes_failed = 0; 571 572 // Outcome of the final Flush() done by FlushAndDisableTracing(). 573 protos::gen::TraceStats_FinalFlushOutcome final_flush_outcome{}; 574 575 // Set to true on the first call to MaybeNotifyAllDataSourcesStarted(). 576 bool did_notify_all_data_source_started = false; 577 578 // Stores all lifecycle events of a particular type (i.e. associated with a 579 // single field id in the TracingServiceEvent proto). 580 struct LifecycleEvent { 581 LifecycleEvent(uint32_t f_id, uint32_t m_size = 1) field_idTracingSession::LifecycleEvent582 : field_id(f_id), max_size(m_size), timestamps(m_size) {} 583 584 // The field id of the event in the TracingServiceEvent proto. 585 uint32_t field_id; 586 587 // Stores the max size of |timestamps|. Set to 1 by default (in 588 // the constructor) but can be overriden in TraceSession constructor 589 // if a larger size is required. 590 uint32_t max_size; 591 592 // Stores the timestamps emitted for each event type (in nanoseconds). 593 // Emitted into the trace and cleared when the consumer next calls 594 // ReadBuffers. 595 base::CircularQueue<int64_t> timestamps; 596 }; 597 std::vector<LifecycleEvent> lifecycle_events; 598 599 using ClockSnapshotData = 600 std::vector<std::pair<uint32_t /*clock_id*/, uint64_t /*ts*/>>; 601 602 // Initial clock snapshot, captured at trace start time (when state goes to 603 // TracingSession::STARTED). Emitted into the trace when the consumer first 604 // calls ReadBuffers(). 605 ClockSnapshotData initial_clock_snapshot; 606 607 // Stores clock snapshots to emit into the trace as a ring buffer. This 608 // buffer is populated both periodically and when lifecycle events happen 609 // but only when significant clock drift is detected. Emitted into the trace 610 // and cleared when the consumer next calls ReadBuffers(). 611 base::CircularQueue<ClockSnapshotData> clock_snapshot_ring_buffer; 612 613 State state = DISABLED; 614 615 // If the consumer detached the session, this variable defines the key used 616 // for identifying the session later when reattaching. 617 std::string detach_key; 618 619 // This is set when the Consumer calls sets |write_into_file| == true in the 620 // TraceConfig. In this case this represents the file we should stream the 621 // trace packets into, rather than returning it to the consumer via 622 // OnTraceData(). 623 base::ScopedFile write_into_file; 624 uint32_t write_period_ms = 0; 625 uint64_t max_file_size_bytes = 0; 626 uint64_t bytes_written_into_file = 0; 627 628 // Set when using SaveTraceForBugreport(). This callback will be called 629 // when the tracing session ends and the data has been saved into the file. 630 std::function<void()> on_disable_callback_for_bugreport; 631 bool seized_for_bugreport = false; 632 633 // Periodic task for snapshotting service events (e.g. clocks, sync markers 634 // etc) 635 base::PeriodicTask snapshot_periodic_task; 636 637 // When non-NULL the packets should be post-processed using the filter. 638 std::unique_ptr<protozero::MessageFilter> trace_filter; 639 uint64_t filter_input_packets = 0; 640 uint64_t filter_input_bytes = 0; 641 uint64_t filter_output_bytes = 0; 642 uint64_t filter_errors = 0; 643 }; 644 645 TracingServiceImpl(const TracingServiceImpl&) = delete; 646 TracingServiceImpl& operator=(const TracingServiceImpl&) = delete; 647 648 DataSourceInstance* SetupDataSource(const TraceConfig::DataSource&, 649 const TraceConfig::ProducerConfig&, 650 const RegisteredDataSource&, 651 TracingSession*); 652 653 // Returns the next available ProducerID that is not in |producers_|. 654 ProducerID GetNextProducerID(); 655 656 // Returns a pointer to the |tracing_sessions_| entry or nullptr if the 657 // session doesn't exists. 658 TracingSession* GetTracingSession(TracingSessionID); 659 660 // Returns a pointer to the |tracing_sessions_| entry, matching the given 661 // uid and detach key, or nullptr if no such session exists. 662 TracingSession* GetDetachedSession(uid_t, const std::string& key); 663 664 // Update the memory guard rail by using the latest information from the 665 // shared memory and trace buffers. 666 void UpdateMemoryGuardrail(); 667 668 void StartDataSourceInstance(ProducerEndpointImpl*, 669 TracingSession*, 670 DataSourceInstance*); 671 void StopDataSourceInstance(ProducerEndpointImpl*, 672 TracingSession*, 673 DataSourceInstance*, 674 bool disable_immediately); 675 void PeriodicSnapshotTask(TracingSessionID); 676 void MaybeSnapshotClocksIntoRingBuffer(TracingSession*); 677 bool SnapshotClocks(TracingSession::ClockSnapshotData*); 678 void SnapshotLifecyleEvent(TracingSession*, 679 uint32_t field_id, 680 bool snapshot_clocks); 681 void EmitClockSnapshot(TracingSession*, 682 TracingSession::ClockSnapshotData, 683 std::vector<TracePacket>*); 684 void EmitSyncMarker(std::vector<TracePacket>*); 685 void EmitStats(TracingSession*, std::vector<TracePacket>*); 686 TraceStats GetTraceStats(TracingSession*); 687 void EmitLifecycleEvents(TracingSession*, std::vector<TracePacket>*); 688 void EmitSeizedForBugreportLifecycleEvent(std::vector<TracePacket>*); 689 void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*); 690 void MaybeEmitSystemInfo(TracingSession*, std::vector<TracePacket>*); 691 void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*); 692 void MaybeNotifyAllDataSourcesStarted(TracingSession*); 693 bool MaybeSaveTraceForBugreport(std::function<void()> callback); 694 void OnFlushTimeout(TracingSessionID, FlushRequestID); 695 void OnDisableTracingTimeout(TracingSessionID); 696 void DisableTracingNotifyConsumerAndFlushFile(TracingSession*); 697 void PeriodicFlushTask(TracingSessionID, bool post_next_only); 698 void CompleteFlush(TracingSessionID tsid, 699 ConsumerEndpoint::FlushCallback callback, 700 bool success); 701 void ScrapeSharedMemoryBuffers(TracingSession*, ProducerEndpointImpl*); 702 void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only); 703 TraceBuffer* GetBufferByID(BufferID); 704 705 // Returns true if `*tracing_session` is waiting for a trigger that hasn't 706 // happened. 707 static bool IsWaitingForTrigger(TracingSession* tracing_session); 708 709 // Reads the buffers from `*tracing_session` and returns them (along with some 710 // metadata packets). 711 // 712 // The function stops when the cumulative size of the return packets exceeds 713 // `threshold` (so it's not a strict upper bound) and sets `*has_more` to 714 // true, or when there are no more packets (and sets `*has_more` to false). 715 std::vector<TracePacket> ReadBuffers(TracingSession* tracing_session, 716 size_t threshold, 717 bool* has_more); 718 719 // If `*tracing_session` has a filter, applies it to `*packets`. Doesn't 720 // change the number of `*packets`, only their content. 721 void MaybeFilterPackets(TracingSession* tracing_session, 722 std::vector<TracePacket>* packets); 723 724 // If `*tracing_session` is configured to write into a file, writes `packets` 725 // into the file. 726 // 727 // Returns true if the file should be closed (because it's full or there has 728 // been an error), false otherwise. 729 bool WriteIntoFile(TracingSession* tracing_session, 730 std::vector<TracePacket> packets); 731 void OnStartTriggersTimeout(TracingSessionID tsid); 732 void MaybeLogUploadEvent(const TraceConfig&, 733 PerfettoStatsdAtom atom, 734 const std::string& trigger_name = ""); 735 void MaybeLogTriggerEvent(const TraceConfig&, 736 PerfettoTriggerAtom atom, 737 const std::string& trigger_name); 738 size_t PurgeExpiredAndCountTriggerInWindow(int64_t now_ns, 739 uint64_t trigger_name_hash); 740 741 base::TaskRunner* const task_runner_; 742 std::unique_ptr<SharedMemory::Factory> shm_factory_; 743 ProducerID last_producer_id_ = 0; 744 DataSourceInstanceID last_data_source_instance_id_ = 0; 745 TracingSessionID last_tracing_session_id_ = 0; 746 FlushRequestID last_flush_request_id_ = 0; 747 uid_t uid_ = 0; 748 749 // Buffer IDs are global across all consumers (because a Producer can produce 750 // data for more than one trace session, hence more than one consumer). 751 IdAllocator<BufferID> buffer_ids_; 752 753 std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_; 754 std::map<ProducerID, ProducerEndpointImpl*> producers_; 755 std::set<ConsumerEndpointImpl*> consumers_; 756 std::map<TracingSessionID, TracingSession> tracing_sessions_; 757 std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_; 758 std::map<std::string, int64_t> session_to_last_trace_s_; 759 760 // Contains timestamps of triggers. 761 // The queue is sorted by timestamp and invocations older than 762 // |trigger_window_ns_| are purged when a trigger happens. 763 base::CircularQueue<TriggerHistory> trigger_history_; 764 765 bool smb_scraping_enabled_ = false; 766 bool lockdown_mode_ = false; 767 uint32_t min_write_period_ms_ = 100; // Overridable for testing. 768 int64_t trigger_window_ns_ = kOneDayInNs; // Overridable for testing. 769 770 std::minstd_rand trigger_probability_rand_; 771 std::uniform_real_distribution<> trigger_probability_dist_; 772 double trigger_rnd_override_for_testing_ = 0; // Overridable for testing. 773 774 uint8_t sync_marker_packet_[32]; // Lazily initialized. 775 size_t sync_marker_packet_size_ = 0; 776 777 // Stats. 778 uint64_t chunks_discarded_ = 0; 779 uint64_t patches_discarded_ = 0; 780 781 PERFETTO_THREAD_CHECKER(thread_checker_) 782 783 base::WeakPtrFactory<TracingServiceImpl> 784 weak_ptr_factory_; // Keep at the end. 785 }; 786 787 } // namespace perfetto 788 789 #endif // SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_ 790