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