blob: 10ca797b540613d1e0ac1ff20d4d9e433bf3c4c8 [file] [log] [blame]
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00001/*
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
Florian Mayer6a1a4d52018-06-08 16:47:07 +010017#ifndef SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
18#define SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000019
20#include <functional>
21#include <map>
22#include <memory>
Primiano Tucci14219ff2019-02-27 12:41:05 +010023#include <mutex>
Primiano Tucci42e2de12017-12-07 16:46:04 +000024#include <set>
Stephen Nusko59847292019-03-22 13:54:08 +000025#include <vector>
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000026
Eric Seckler57c89d92018-10-26 15:11:55 +010027#include "perfetto/base/gtest_prod_util.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010028#include "perfetto/base/logging.h"
Eric Secklerf3f524b2018-12-13 09:09:34 +000029#include "perfetto/base/optional.h"
Sami Kyostilafbccb3c2018-03-21 14:00:47 +000030#include "perfetto/base/time.h"
Primiano Tucci42e2de12017-12-07 16:46:04 +000031#include "perfetto/base/weak_ptr.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000032#include "perfetto/tracing/core/basic_types.h"
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000033#include "perfetto/tracing/core/commit_data_request.h"
Primiano Tucci53589332017-12-19 11:31:13 +010034#include "perfetto/tracing/core/data_source_descriptor.h"
Eric Seckler7b0c9452019-03-18 13:14:36 +000035#include "perfetto/tracing/core/observable_events.h"
Primiano Tucci53589332017-12-19 11:31:13 +010036#include "perfetto/tracing/core/shared_memory_abi.h"
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -080037#include "perfetto/tracing/core/trace_config.h"
Eric Secklereaf29ed2019-01-23 09:53:55 +000038#include "perfetto/tracing/core/trace_stats.h"
Florian Mayer6a1a4d52018-06-08 16:47:07 +010039#include "perfetto/tracing/core/tracing_service.h"
Primiano Tucci53589332017-12-19 11:31:13 +010040#include "src/tracing/core/id_allocator.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000041
42namespace perfetto {
43
44namespace base {
45class TaskRunner;
46} // namespace base
47
Primiano Tucci42e2de12017-12-07 16:46:04 +000048class Consumer;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000049class DataSourceConfig;
50class Producer;
51class SharedMemory;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010052class SharedMemoryArbiterImpl;
Hector Dearman6214c8f2018-03-27 16:16:22 +010053class TraceBuffer;
Primiano Tucci42e2de12017-12-07 16:46:04 +000054class TraceConfig;
Sami Kyostilafbccb3c2018-03-21 14:00:47 +000055class TracePacket;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000056
57// The tracing service business logic.
Florian Mayer6a1a4d52018-06-08 16:47:07 +010058class TracingServiceImpl : public TracingService {
Eric Seckler4ff03e52019-03-15 10:10:30 +000059 private:
60 struct DataSourceInstance;
61
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000062 public:
Primiano Tucci1a1951d2018-04-04 21:08:16 +020063 static constexpr size_t kDefaultShmSize = 256 * 1024ul;
Primiano Tuccie7ca7c62018-04-07 08:28:03 +020064 static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
Primiano Tuccibaeecf12018-07-25 12:02:20 +010065 static constexpr uint32_t kDataSourceStopTimeoutMs = 5000;
Primiano Tucci9754d0d2018-09-15 12:41:46 +010066 static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d,
67 0x42, 0xba, 0x81, 0xdc, 0x33, 0x32,
68 0x6d, 0x57, 0xa0, 0x79};
Primiano Tucci1a1951d2018-04-04 21:08:16 +020069
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000070 // The implementation behind the service endpoint exposed to each producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +010071 class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000072 public:
73 ProducerEndpointImpl(ProducerID,
Sami Kyostila32e0b542018-02-14 08:55:43 +000074 uid_t uid,
Florian Mayer6a1a4d52018-06-08 16:47:07 +010075 TracingServiceImpl*,
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000076 base::TaskRunner*,
Isabelle Taylor86262cb2018-03-27 16:00:54 +010077 Producer*,
Oystein Eftevaagc8d2f072019-03-29 09:41:04 -070078 const std::string& producer_name,
Eric Seckler062ed502019-05-23 09:02:57 +010079 bool in_process,
80 bool smb_scraping_enabled);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000081 ~ProducerEndpointImpl() override;
82
Florian Mayer6a1a4d52018-06-08 16:47:07 +010083 // TracingService::ProducerEndpoint implementation.
Primiano Tucci9daa4832018-03-28 23:28:17 +010084 void RegisterDataSource(const DataSourceDescriptor&) override;
85 void UnregisterDataSource(const std::string& name) override;
Eric Seckler1c4e1ac2018-11-29 10:23:14 +000086 void RegisterTraceWriter(uint32_t writer_id,
87 uint32_t target_buffer) override;
88 void UnregisterTraceWriter(uint32_t writer_id) override;
Primiano Tucci3e69ed92018-03-14 14:52:29 +000089 void CommitData(const CommitDataRequest&, CommitDataCallback) override;
Isabelle Taylor69faa902018-03-21 15:42:03 +000090 void SetSharedMemory(std::unique_ptr<SharedMemory>);
Primiano Tucciaf429f92017-12-19 01:51:50 +010091 std::unique_ptr<TraceWriter> CreateTraceWriter(BufferID) override;
Oystein Eftevaagf4cccb52019-04-17 13:31:29 -070092 SharedMemoryArbiter* GetInProcessShmemArbiter() override;
Primiano Tuccid52e6272018-04-06 19:06:53 +020093 void NotifyFlushComplete(FlushRequestID) override;
Eric Seckler4ff03e52019-03-15 10:10:30 +000094 void NotifyDataSourceStarted(DataSourceInstanceID) override;
Primiano Tuccibaeecf12018-07-25 12:02:20 +010095 void NotifyDataSourceStopped(DataSourceInstanceID) override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000096 SharedMemory* shared_memory() const override;
Isabelle Taylor69faa902018-03-21 15:42:03 +000097 size_t shared_buffer_page_size_kb() const override;
Stephen Nusko1393ffd2019-03-22 13:54:58 +000098 void ActivateTriggers(const std::vector<std::string>&) override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000099
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100100 void OnTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +0100101 void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&);
Primiano Tucciafb72b52018-09-25 09:37:24 +0100102 void StartDataSource(DataSourceInstanceID, const DataSourceConfig&);
Primiano Tucci674076d2018-10-01 10:41:09 +0100103 void StopDataSource(DataSourceInstanceID);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100104 void Flush(FlushRequestID, const std::vector<DataSourceInstanceID>&);
Eric Seckler6dc23592018-11-30 10:59:06 +0000105 void OnFreeBuffers(const std::vector<BufferID>& target_buffers);
Ryan Savitski33868d52019-05-13 10:56:14 +0100106 void ClearIncrementalState(const std::vector<DataSourceInstanceID>&);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100107
Eric Secklerdd0ad102018-12-06 11:32:04 +0000108 bool is_allowed_target_buffer(BufferID buffer_id) const {
109 return allowed_target_buffers_.count(buffer_id);
110 }
111
Eric Secklerf3f524b2018-12-13 09:09:34 +0000112 base::Optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
113 const auto it = writers_.find(writer_id);
114 if (it != writers_.end())
115 return it->second;
116 return base::nullopt;
117 }
118
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000119 private:
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100120 friend class TracingServiceImpl;
121 friend class TracingServiceImplTest;
Eric Seckler062ed502019-05-23 09:02:57 +0100122 friend class TracingIntegrationTest;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000123 ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
124 ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
125
126 ProducerID const id_;
Sami Kyostila32e0b542018-02-14 08:55:43 +0000127 const uid_t uid_;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100128 TracingServiceImpl* const service_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000129 base::TaskRunner* const task_runner_;
130 Producer* producer_;
131 std::unique_ptr<SharedMemory> shared_memory_;
Isabelle Taylor69faa902018-03-21 15:42:03 +0000132 size_t shared_buffer_page_size_kb_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100133 SharedMemoryABI shmem_abi_;
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200134 size_t shmem_size_hint_bytes_ = 0;
Isabelle Taylor86262cb2018-03-27 16:00:54 +0100135 const std::string name_;
Oystein Eftevaagc8d2f072019-03-29 09:41:04 -0700136 bool in_process_;
Eric Seckler062ed502019-05-23 09:02:57 +0100137 bool smb_scraping_enabled_;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100138
Eric Seckler6dc23592018-11-30 10:59:06 +0000139 // Set of the global target_buffer IDs that the producer is configured to
140 // write into in any active tracing session.
141 std::set<BufferID> allowed_target_buffers_;
142
Eric Secklerf3f524b2018-12-13 09:09:34 +0000143 // Maps registered TraceWriter IDs to their target buffers as registered by
144 // the producer. Note that producers aren't required to register their
145 // writers, so we may see commits of chunks with WriterIDs that aren't
146 // contained in this map. However, if a producer does register a writer, the
147 // service will prevent the writer from writing into any other buffer than
148 // the one associated with it here. The BufferIDs stored in this map are
149 // untrusted, so need to be verified against |allowed_target_buffers_|
150 // before use.
151 std::map<WriterID, BufferID> writers_;
152
Oystein Eftevaagc8d2f072019-03-29 09:41:04 -0700153 // This is used only in in-process configurations.
Primiano Tucci14219ff2019-02-27 12:41:05 +0100154 // SharedMemoryArbiterImpl methods themselves are thread-safe.
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100155 std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;
Primiano Tucci14219ff2019-02-27 12:41:05 +0100156
Florian Mayercd08ec62018-01-31 17:49:25 +0000157 PERFETTO_THREAD_CHECKER(thread_checker_)
Primiano Tuccidca727d2018-04-04 11:31:55 +0200158 base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_; // Keep last.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000159 };
160
Primiano Tucci42e2de12017-12-07 16:46:04 +0000161 // The implementation behind the service endpoint exposed to each consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100162 class ConsumerEndpointImpl : public TracingService::ConsumerEndpoint {
Primiano Tucci42e2de12017-12-07 16:46:04 +0000163 public:
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100164 ConsumerEndpointImpl(TracingServiceImpl*,
165 base::TaskRunner*,
166 Consumer*,
167 uid_t uid);
Primiano Tucci42e2de12017-12-07 16:46:04 +0000168 ~ConsumerEndpointImpl() override;
169
Primiano Tuccidca727d2018-04-04 11:31:55 +0200170 void NotifyOnTracingDisabled();
Primiano Tucci42e2de12017-12-07 16:46:04 +0000171 base::WeakPtr<ConsumerEndpointImpl> GetWeakPtr();
172
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100173 // TracingService::ConsumerEndpoint implementation.
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100174 void EnableTracing(const TraceConfig&, base::ScopedFile) override;
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -0800175 void ChangeTraceConfig(const TraceConfig& cfg) override;
Primiano Tucci674076d2018-10-01 10:41:09 +0100176 void StartTracing() override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000177 void DisableTracing() override;
178 void ReadBuffers() override;
179 void FreeBuffers() override;
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100180 void Flush(uint32_t timeout_ms, FlushCallback) override;
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100181 void Detach(const std::string& key) override;
182 void Attach(const std::string& key) override;
Eric Secklereaf29ed2019-01-23 09:53:55 +0000183 void GetTraceStats() override;
Eric Seckler7b0c9452019-03-18 13:14:36 +0000184 void ObserveEvents(uint32_t enabled_event_types) override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000185
Eric Seckler7b0c9452019-03-18 13:14:36 +0000186 // If |observe_data_source_instances == true|, will queue a task to notify
187 // the consumer about the state change.
Eric Seckler4ff03e52019-03-15 10:10:30 +0000188 void OnDataSourceInstanceStateChange(const ProducerEndpointImpl&,
Eric Seckler7b0c9452019-03-18 13:14:36 +0000189 const DataSourceInstance&);
Eric Seckler4ff03e52019-03-15 10:10:30 +0000190
Primiano Tucci42e2de12017-12-07 16:46:04 +0000191 private:
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100192 friend class TracingServiceImpl;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000193 ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
194 ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
195
Eric Seckler7b0c9452019-03-18 13:14:36 +0000196 // Returns a pointer to an ObservableEvents object that the caller can fill
197 // and schedules a task to send the ObservableEvents to the consumer.
198 ObservableEvents* AddObservableEvents();
199
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100200 base::TaskRunner* const task_runner_;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100201 TracingServiceImpl* const service_;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000202 Consumer* const consumer_;
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100203 uid_t const uid_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000204 TracingSessionID tracing_session_id_ = 0;
Eric Seckler7b0c9452019-03-18 13:14:36 +0000205
206 // Whether the consumer is interested in DataSourceInstance state change
207 // events.
208 uint32_t enabled_observable_event_types_ = ObservableEventType::kNone;
209 // ObservableEvents that will be sent to the consumer. If set, a task to
210 // flush the events to the consumer has been queued.
211 std::unique_ptr<ObservableEvents> observable_events_;
212
Florian Mayercd08ec62018-01-31 17:49:25 +0000213 PERFETTO_THREAD_CHECKER(thread_checker_)
Primiano Tuccidca727d2018-04-04 11:31:55 +0200214 base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_; // Keep last.
Primiano Tucci42e2de12017-12-07 16:46:04 +0000215 };
216
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100217 explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>,
218 base::TaskRunner*);
219 ~TracingServiceImpl() override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000220
Primiano Tucci42e2de12017-12-07 16:46:04 +0000221 // Called by ProducerEndpointImpl.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000222 void DisconnectProducer(ProducerID);
Primiano Tucci9daa4832018-03-28 23:28:17 +0100223 void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
224 void UnregisterDataSource(ProducerID, const std::string& name);
Primiano Tucci53589332017-12-19 11:31:13 +0100225 void CopyProducerPageIntoLogBuffer(ProducerID,
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000226 uid_t,
227 WriterID,
228 ChunkID,
Primiano Tucci53589332017-12-19 11:31:13 +0100229 BufferID,
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000230 uint16_t num_fragments,
231 uint8_t chunk_flags,
Eric Secklerb77b27e2018-12-17 11:42:52 +0000232 bool chunk_complete,
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000233 const uint8_t* src,
234 size_t size);
235 void ApplyChunkPatches(ProducerID,
236 const std::vector<CommitDataRequest::ChunkToPatch>&);
Primiano Tuccid52e6272018-04-06 19:06:53 +0200237 void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
Eric Seckler4ff03e52019-03-15 10:10:30 +0000238 void NotifyDataSourceStarted(ProducerID, const DataSourceInstanceID);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100239 void NotifyDataSourceStopped(ProducerID, const DataSourceInstanceID);
Stephen Nusko59847292019-03-22 13:54:08 +0000240 void ActivateTriggers(ProducerID, const std::vector<std::string>& triggers);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000241
Primiano Tucci42e2de12017-12-07 16:46:04 +0000242 // Called by ConsumerEndpointImpl.
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100243 bool DetachConsumer(ConsumerEndpointImpl*, const std::string& key);
244 bool AttachConsumer(ConsumerEndpointImpl*, const std::string& key);
Primiano Tucci42e2de12017-12-07 16:46:04 +0000245 void DisconnectConsumer(ConsumerEndpointImpl*);
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100246 bool EnableTracing(ConsumerEndpointImpl*,
247 const TraceConfig&,
248 base::ScopedFile);
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -0800249 void ChangeTraceConfig(ConsumerEndpointImpl*, const TraceConfig&);
250
Primiano Tucci674076d2018-10-01 10:41:09 +0100251 bool StartTracing(TracingSessionID);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100252 void DisableTracing(TracingSessionID, bool disable_immediately = false);
Primiano Tuccid52e6272018-04-06 19:06:53 +0200253 void Flush(TracingSessionID tsid,
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100254 uint32_t timeout_ms,
Primiano Tuccid52e6272018-04-06 19:06:53 +0200255 ConsumerEndpoint::FlushCallback);
256 void FlushAndDisableTracing(TracingSessionID);
Primiano Tucci20d441d2018-01-16 09:25:51 +0000257 void ReadBuffers(TracingSessionID, ConsumerEndpointImpl*);
258 void FreeBuffers(TracingSessionID);
Primiano Tucci42e2de12017-12-07 16:46:04 +0000259
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000260 // Service implementation.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100261 std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000262 Producer*,
Sami Kyostila32e0b542018-02-14 08:55:43 +0000263 uid_t uid,
Isabelle Taylor86262cb2018-03-27 16:00:54 +0100264 const std::string& producer_name,
Oystein Eftevaagc8d2f072019-03-29 09:41:04 -0700265 size_t shared_memory_size_hint_bytes = 0,
Eric Seckler062ed502019-05-23 09:02:57 +0100266 bool in_process = false,
267 ProducerSMBScrapingMode smb_scraping_mode =
268 ProducerSMBScrapingMode::kDefault) override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000269
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100270 std::unique_ptr<TracingService::ConsumerEndpoint> ConnectConsumer(
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100271 Consumer*,
272 uid_t) override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000273
Eric Seckler062ed502019-05-23 09:02:57 +0100274 // Set whether SMB scraping should be enabled by default or not. Producers can
275 // override this setting for their own SMBs.
Eric Secklera01e28a2019-01-08 11:21:04 +0000276 void SetSMBScrapingEnabled(bool enabled) override {
277 smb_scraping_enabled_ = enabled;
278 }
279
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000280 // Exposed mainly for testing.
281 size_t num_producers() const { return producers_.size(); }
282 ProducerEndpointImpl* GetProducer(ProducerID) const;
283
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100284 uint32_t override_data_source_test_timeout_ms_for_testing = 0;
285
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000286 private:
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100287 friend class TracingServiceImplTest;
Eric Seckler062ed502019-05-23 09:02:57 +0100288 friend class TracingIntegrationTest;
Primiano Tucci081d46a2018-02-28 11:09:43 +0000289
Primiano Tucci53589332017-12-19 11:31:13 +0100290 struct RegisteredDataSource {
291 ProducerID producer_id;
Primiano Tucci53589332017-12-19 11:31:13 +0100292 DataSourceDescriptor descriptor;
293 };
294
Sami Kyostila06487a22018-02-27 13:48:38 +0000295 // Represents an active data source for a tracing session.
296 struct DataSourceInstance {
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000297 DataSourceInstance(DataSourceInstanceID id,
298 const DataSourceConfig& cfg,
299 const std::string& ds_name,
Eric Seckler4ff03e52019-03-15 10:10:30 +0000300 bool notify_on_start,
Ryan Savitski33868d52019-05-13 10:56:14 +0100301 bool notify_on_stop,
302 bool handles_incremental_state_invalidation)
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000303 : instance_id(id),
304 config(cfg),
305 data_source_name(ds_name),
Eric Seckler4ff03e52019-03-15 10:10:30 +0000306 will_notify_on_start(notify_on_start),
Ryan Savitski33868d52019-05-13 10:56:14 +0100307 will_notify_on_stop(notify_on_stop),
308 handles_incremental_state_clear(
309 handles_incremental_state_invalidation) {}
Primiano Tucci674076d2018-10-01 10:41:09 +0100310 DataSourceInstance(const DataSourceInstance&) = delete;
311 DataSourceInstance& operator=(const DataSourceInstance&) = delete;
Primiano Tucci674076d2018-10-01 10:41:09 +0100312
Sami Kyostila06487a22018-02-27 13:48:38 +0000313 DataSourceInstanceID instance_id;
Primiano Tucci674076d2018-10-01 10:41:09 +0100314 DataSourceConfig config;
Primiano Tucci9daa4832018-03-28 23:28:17 +0100315 std::string data_source_name;
Eric Seckler4ff03e52019-03-15 10:10:30 +0000316 bool will_notify_on_start;
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100317 bool will_notify_on_stop;
Ryan Savitski33868d52019-05-13 10:56:14 +0100318 bool handles_incremental_state_clear;
Eric Seckler4ff03e52019-03-15 10:10:30 +0000319
320 enum DataSourceInstanceState {
321 CONFIGURED,
322 STARTING,
323 STARTED,
324 STOPPING,
325 STOPPED
326 };
327 DataSourceInstanceState state = CONFIGURED;
Sami Kyostila06487a22018-02-27 13:48:38 +0000328 };
329
Primiano Tuccid52e6272018-04-06 19:06:53 +0200330 struct PendingFlush {
331 std::set<ProducerID> producers;
332 ConsumerEndpoint::FlushCallback callback;
333 explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
334 };
335
Primiano Tucci53589332017-12-19 11:31:13 +0100336 // Holds the state of a tracing session. A tracing session is uniquely bound
337 // a specific Consumer. Each Consumer can own one or more sessions.
338 struct TracingSession {
Primiano Tucci674076d2018-10-01 10:41:09 +0100339 enum State {
340 DISABLED = 0,
341 CONFIGURED,
342 STARTED,
343 DISABLING_WAITING_STOP_ACKS
344 };
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100345
346 TracingSession(TracingSessionID, ConsumerEndpointImpl*, const TraceConfig&);
Primiano Tucci20d441d2018-01-16 09:25:51 +0000347
348 size_t num_buffers() const { return buffers_index.size(); }
349
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100350 uint32_t delay_to_next_write_period_ms() const {
Sami Kyostila01c45f02018-03-29 15:43:10 +0100351 PERFETTO_DCHECK(write_period_ms > 0);
352 return write_period_ms -
353 (base::GetWallTimeMs().count() % write_period_ms);
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100354 }
355
Florian Mayere563f662019-01-09 11:04:50 +0000356 uint32_t flush_timeout_ms() {
357 uint32_t timeout_ms = config.flush_timeout_ms();
358 return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs;
359 }
360
Eric Secklerd0ac7ca2019-02-06 09:13:45 +0000361 PacketSequenceID GetPacketSequenceID(ProducerID producer_id,
362 WriterID writer_id) {
363 auto key = std::make_pair(producer_id, writer_id);
364 auto it = packet_sequence_ids.find(key);
365 if (it != packet_sequence_ids.end())
366 return it->second;
367 // We shouldn't run out of sequence IDs (producer ID is 16 bit, writer IDs
368 // are limited to 1024).
369 static_assert(kMaxPacketSequenceID > kMaxProducerID * kMaxWriterID,
370 "PacketSequenceID value space doesn't cover service "
371 "sequence ID and all producer/writer ID combinations!");
372 PERFETTO_DCHECK(last_packet_sequence_id < kMaxPacketSequenceID);
373 PacketSequenceID sequence_id = ++last_packet_sequence_id;
374 packet_sequence_ids[key] = sequence_id;
375 return sequence_id;
376 }
377
Eric Seckler4ff03e52019-03-15 10:10:30 +0000378 DataSourceInstance* GetDataSourceInstance(
379 ProducerID producer_id,
380 DataSourceInstanceID instance_id) {
381 for (auto& inst_kv : data_source_instances) {
382 if (inst_kv.first != producer_id ||
383 inst_kv.second.instance_id != instance_id) {
384 continue;
385 }
386 return &inst_kv.second;
387 }
388 return nullptr;
389 }
390
391 bool AllDataSourceInstancesStopped() {
392 for (const auto& inst_kv : data_source_instances) {
393 if (inst_kv.second.state != DataSourceInstance::STOPPED)
394 return false;
395 }
396 return true;
397 }
398
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100399 const TracingSessionID id;
400
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100401 // The consumer that started the session.
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100402 // Can be nullptr if the consumer detached from the session.
403 ConsumerEndpointImpl* consumer_maybe_null;
404
405 // Unix uid of the consumer. This is valid even after the consumer detaches
406 // and does not change for the entire duration of the session. It is used to
407 // prevent that a consumer re-attaches to a session from a different uid.
408 uid_t const consumer_uid;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100409
Stephen Nusko59847292019-03-22 13:54:08 +0000410 // The list of triggers this session received while alive and the time they
411 // were received at. This is used to insert 'fake' packets back to the
412 // consumer so they can tell when some event happened. The order matches the
413 // order they were received.
Stephen Nusko70ea3302019-04-01 19:44:40 +0100414 struct TriggerInfo {
415 uint64_t boot_time_ns;
416 std::string trigger_name;
417 std::string producer_name;
418 uid_t producer_uid;
419 };
420 std::vector<TriggerInfo> received_triggers;
Stephen Nusko59847292019-03-22 13:54:08 +0000421
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -0800422 // The trace config provided by the Consumer when calling
423 // EnableTracing(), plus any updates performed by ChangeTraceConfig.
424 TraceConfig config;
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -0800425
Primiano Tucci53589332017-12-19 11:31:13 +0100426 // List of data source instances that have been enabled on the various
427 // producers for this tracing session.
Ryan Savitski33868d52019-05-13 10:56:14 +0100428 // TODO(rsavitski): at the time of writing, the map structure is unused
429 // (even when the calling code has a key). This is also an opportunity to
430 // consider an alternative data type, e.g. a map of vectors.
Sami Kyostila06487a22018-02-27 13:48:38 +0000431 std::multimap<ProducerID, DataSourceInstance> data_source_instances;
Primiano Tucci53589332017-12-19 11:31:13 +0100432
Primiano Tuccid52e6272018-04-06 19:06:53 +0200433 // For each Flush(N) request, keeps track of the set of producers for which
434 // we are still awaiting a NotifyFlushComplete(N) ack.
435 std::map<FlushRequestID, PendingFlush> pending_flushes;
436
Primiano Tucci20d441d2018-01-16 09:25:51 +0000437 // Maps a per-trace-session buffer index into the corresponding global
438 // BufferID (shared namespace amongst all consumers). This vector has as
439 // many entries as |config.buffers_size()|.
440 std::vector<BufferID> buffers_index;
Sami Kyostilafbccb3c2018-03-21 14:00:47 +0000441
Eric Secklerd0ac7ca2019-02-06 09:13:45 +0000442 std::map<std::pair<ProducerID, WriterID>, PacketSequenceID>
443 packet_sequence_ids;
444 PacketSequenceID last_packet_sequence_id = kServicePacketSequenceID;
445
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100446 // When the last snapshots (clock, stats, sync marker) were emitted into
447 // the output stream.
448 base::TimeMillis last_snapshot_time = {};
Primiano Tucci5e33cad2018-04-30 14:41:25 +0100449
Sami Kyostila200bd2e2018-03-26 12:24:10 +0100450 // Whether we mirrored the trace config back to the trace output yet.
451 bool did_emit_config = false;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100452
Hector Dearman685f7522019-03-12 14:28:56 +0000453 // Whether we put the system info into the trace output yet.
454 bool did_emit_system_info = false;
455
Stephen Nusko70ea3302019-04-01 19:44:40 +0100456 // The number of received triggers we've emitted into the trace output.
457 size_t num_triggers_emitted_into_trace = 0;
458
Hector Dearmane004a572019-05-13 17:51:43 +0100459 // Initial clock snapshot, captured at trace start time (when state goes
460 // to TracingSession::STARTED). Emitted into the trace when the consumer
461 // first begins reading the trace.
462 std::vector<TracePacket> initial_clock_snapshot_;
463
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100464 State state = DISABLED;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100465
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100466 // If the consumer detached the session, this variable defines the key used
467 // for identifying the session later when reattaching.
468 std::string detach_key;
469
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100470 // This is set when the Consumer calls sets |write_into_file| == true in the
471 // TraceConfig. In this case this represents the file we should stream the
472 // trace packets into, rather than returning it to the consumer via
473 // OnTraceData().
474 base::ScopedFile write_into_file;
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100475 uint32_t write_period_ms = 0;
476 uint64_t max_file_size_bytes = 0;
477 uint64_t bytes_written_into_file = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100478 };
479
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100480 TracingServiceImpl(const TracingServiceImpl&) = delete;
481 TracingServiceImpl& operator=(const TracingServiceImpl&) = delete;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000482
Primiano Tucci674076d2018-10-01 10:41:09 +0100483 DataSourceInstance* SetupDataSource(const TraceConfig::DataSource&,
484 const TraceConfig::ProducerConfig&,
485 const RegisteredDataSource&,
486 TracingSession*);
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -0800487
Primiano Tucci081d46a2018-02-28 11:09:43 +0000488 // Returns the next available ProducerID that is not in |producers_|.
489 ProducerID GetNextProducerID();
490
Primiano Tucci20d441d2018-01-16 09:25:51 +0000491 // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
492 // session doesn't exists.
493 TracingSession* GetTracingSession(TracingSessionID);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000494
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100495 // Returns a pointer to the |tracing_sessions_| entry, matching the given
496 // uid and detach key, or nullptr if no such session exists.
497 TracingSession* GetDetachedSession(uid_t, const std::string& key);
498
Lalit Maganti485faff2018-03-06 11:51:35 +0000499 // Update the memory guard rail by using the latest information from the
500 // shared memory and trace buffers.
501 void UpdateMemoryGuardrail();
502
Eric Seckler4ff03e52019-03-15 10:10:30 +0000503 void StartDataSourceInstance(ProducerEndpointImpl* producer,
504 TracingSession* tracing_session,
505 DataSourceInstance* instance);
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100506 void SnapshotSyncMarker(std::vector<TracePacket>*);
Primiano Tucci80cb4182019-05-14 09:37:56 +0100507 void SnapshotClocks(std::vector<TracePacket>*, bool set_root_timestamp);
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100508 void SnapshotStats(TracingSession*, std::vector<TracePacket>*);
Eric Secklereaf29ed2019-01-23 09:53:55 +0000509 TraceStats GetTraceStats(TracingSession* tracing_session);
Sami Kyostila200bd2e2018-03-26 12:24:10 +0100510 void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
Hector Dearman685f7522019-03-12 14:28:56 +0000511 void MaybeEmitSystemInfo(TracingSession*, std::vector<TracePacket>*);
Stephen Nusko70ea3302019-04-01 19:44:40 +0100512 void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*);
Primiano Tuccid52e6272018-04-06 19:06:53 +0200513 void OnFlushTimeout(TracingSessionID, FlushRequestID);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100514 void OnDisableTracingTimeout(TracingSessionID);
515 void DisableTracingNotifyConsumerAndFlushFile(TracingSession*);
Primiano Tuccicaa57802018-11-25 11:07:07 +0000516 void PeriodicFlushTask(TracingSessionID, bool post_next_only);
Eric Secklera01e28a2019-01-08 11:21:04 +0000517 void CompleteFlush(TracingSessionID tsid,
518 ConsumerEndpoint::FlushCallback callback,
519 bool success);
520 void ScrapeSharedMemoryBuffers(TracingSession* tracing_session,
521 ProducerEndpointImpl* producer);
Ryan Savitski33868d52019-05-13 10:56:14 +0100522 void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only);
Hector Dearman6214c8f2018-03-27 16:16:22 +0100523 TraceBuffer* GetBufferByID(BufferID);
Stephen Nusko59847292019-03-22 13:54:08 +0000524 void OnStartTriggersTimeout(TracingSessionID tsid);
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000525
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000526 base::TaskRunner* const task_runner_;
Primiano Tucci53589332017-12-19 11:31:13 +0100527 std::unique_ptr<SharedMemory::Factory> shm_factory_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000528 ProducerID last_producer_id_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100529 DataSourceInstanceID last_data_source_instance_id_ = 0;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000530 TracingSessionID last_tracing_session_id_ = 0;
Primiano Tuccid52e6272018-04-06 19:06:53 +0200531 FlushRequestID last_flush_request_id_ = 0;
Primiano Tucci5e33cad2018-04-30 14:41:25 +0100532 uid_t uid_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100533
534 // Buffer IDs are global across all consumers (because a Producer can produce
535 // data for more than one trace session, hence more than one consumer).
Primiano Tucci20d441d2018-01-16 09:25:51 +0000536 IdAllocator<BufferID> buffer_ids_;
Primiano Tucci53589332017-12-19 11:31:13 +0100537
538 std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000539 std::map<ProducerID, ProducerEndpointImpl*> producers_;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000540 std::set<ConsumerEndpointImpl*> consumers_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000541 std::map<TracingSessionID, TracingSession> tracing_sessions_;
Hector Dearman6214c8f2018-03-27 16:16:22 +0100542 std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000543
Eric Secklera01e28a2019-01-08 11:21:04 +0000544 bool smb_scraping_enabled_ = false;
Florian Mayer61c55482018-03-06 14:43:54 +0000545 bool lockdown_mode_ = false;
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100546 uint32_t min_write_period_ms_ = 100; // Overridable for testing.
547
548 uint8_t sync_marker_packet_[32]; // Lazily initialized.
549 size_t sync_marker_packet_size_ = 0;
Florian Mayer61c55482018-03-06 14:43:54 +0000550
Eric Seckler2c72bd82019-02-08 15:01:34 +0000551 // Stats.
552 uint64_t chunks_discarded_ = 0;
553 uint64_t patches_discarded_ = 0;
554
Florian Mayercd08ec62018-01-31 17:49:25 +0000555 PERFETTO_THREAD_CHECKER(thread_checker_)
556
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100557 base::WeakPtrFactory<TracingServiceImpl>
558 weak_ptr_factory_; // Keep at the end.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000559};
560
561} // namespace perfetto
562
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100563#endif // SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_