• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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