blob: 37313366a68759027854438c99e82d320b07a114 [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>
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000025
Eric Seckler57c89d92018-10-26 15:11:55 +010026#include "perfetto/base/gtest_prod_util.h"
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010027#include "perfetto/base/logging.h"
Eric Secklerf3f524b2018-12-13 09:09:34 +000028#include "perfetto/base/optional.h"
Sami Kyostilafbccb3c2018-03-21 14:00:47 +000029#include "perfetto/base/time.h"
Primiano Tucci42e2de12017-12-07 16:46:04 +000030#include "perfetto/base/weak_ptr.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000031#include "perfetto/tracing/core/basic_types.h"
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000032#include "perfetto/tracing/core/commit_data_request.h"
Primiano Tucci53589332017-12-19 11:31:13 +010033#include "perfetto/tracing/core/data_source_descriptor.h"
Primiano Tucci53589332017-12-19 11:31:13 +010034#include "perfetto/tracing/core/shared_memory_abi.h"
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -080035#include "perfetto/tracing/core/trace_config.h"
Eric Secklereaf29ed2019-01-23 09:53:55 +000036#include "perfetto/tracing/core/trace_stats.h"
Florian Mayer6a1a4d52018-06-08 16:47:07 +010037#include "perfetto/tracing/core/tracing_service.h"
Primiano Tucci53589332017-12-19 11:31:13 +010038#include "src/tracing/core/id_allocator.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000039
40namespace perfetto {
41
42namespace base {
43class TaskRunner;
44} // namespace base
45
Primiano Tucci42e2de12017-12-07 16:46:04 +000046class Consumer;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000047class DataSourceConfig;
48class Producer;
49class SharedMemory;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010050class SharedMemoryArbiterImpl;
Hector Dearman6214c8f2018-03-27 16:16:22 +010051class TraceBuffer;
Primiano Tucci42e2de12017-12-07 16:46:04 +000052class TraceConfig;
Sami Kyostilafbccb3c2018-03-21 14:00:47 +000053class TracePacket;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000054
55// The tracing service business logic.
Florian Mayer6a1a4d52018-06-08 16:47:07 +010056class TracingServiceImpl : public TracingService {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000057 public:
Primiano Tucci1a1951d2018-04-04 21:08:16 +020058 static constexpr size_t kDefaultShmSize = 256 * 1024ul;
Primiano Tuccie7ca7c62018-04-07 08:28:03 +020059 static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
Primiano Tuccibaeecf12018-07-25 12:02:20 +010060 static constexpr uint32_t kDataSourceStopTimeoutMs = 5000;
Primiano Tucci9754d0d2018-09-15 12:41:46 +010061 static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d,
62 0x42, 0xba, 0x81, 0xdc, 0x33, 0x32,
63 0x6d, 0x57, 0xa0, 0x79};
Primiano Tucci1a1951d2018-04-04 21:08:16 +020064
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000065 // The implementation behind the service endpoint exposed to each producer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +010066 class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000067 public:
68 ProducerEndpointImpl(ProducerID,
Sami Kyostila32e0b542018-02-14 08:55:43 +000069 uid_t uid,
Florian Mayer6a1a4d52018-06-08 16:47:07 +010070 TracingServiceImpl*,
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000071 base::TaskRunner*,
Isabelle Taylor86262cb2018-03-27 16:00:54 +010072 Producer*,
73 const std::string& producer_name);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000074 ~ProducerEndpointImpl() override;
75
Florian Mayer6a1a4d52018-06-08 16:47:07 +010076 // TracingService::ProducerEndpoint implementation.
Primiano Tucci9daa4832018-03-28 23:28:17 +010077 void RegisterDataSource(const DataSourceDescriptor&) override;
78 void UnregisterDataSource(const std::string& name) override;
Eric Seckler1c4e1ac2018-11-29 10:23:14 +000079 void RegisterTraceWriter(uint32_t writer_id,
80 uint32_t target_buffer) override;
81 void UnregisterTraceWriter(uint32_t writer_id) override;
Primiano Tucci3e69ed92018-03-14 14:52:29 +000082 void CommitData(const CommitDataRequest&, CommitDataCallback) override;
Isabelle Taylor69faa902018-03-21 15:42:03 +000083 void SetSharedMemory(std::unique_ptr<SharedMemory>);
Primiano Tucciaf429f92017-12-19 01:51:50 +010084 std::unique_ptr<TraceWriter> CreateTraceWriter(BufferID) override;
Primiano Tuccid52e6272018-04-06 19:06:53 +020085 void NotifyFlushComplete(FlushRequestID) override;
Primiano Tuccibaeecf12018-07-25 12:02:20 +010086 void NotifyDataSourceStopped(DataSourceInstanceID) override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000087 SharedMemory* shared_memory() const override;
Isabelle Taylor69faa902018-03-21 15:42:03 +000088 size_t shared_buffer_page_size_kb() const override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000089
Primiano Tuccibaeecf12018-07-25 12:02:20 +010090 void OnTracingSetup();
Primiano Tucci674076d2018-10-01 10:41:09 +010091 void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&);
Primiano Tucciafb72b52018-09-25 09:37:24 +010092 void StartDataSource(DataSourceInstanceID, const DataSourceConfig&);
Primiano Tucci674076d2018-10-01 10:41:09 +010093 void StopDataSource(DataSourceInstanceID);
Primiano Tuccibaeecf12018-07-25 12:02:20 +010094 void Flush(FlushRequestID, const std::vector<DataSourceInstanceID>&);
Eric Seckler6dc23592018-11-30 10:59:06 +000095 void OnFreeBuffers(const std::vector<BufferID>& target_buffers);
Primiano Tuccibaeecf12018-07-25 12:02:20 +010096
Eric Secklerdd0ad102018-12-06 11:32:04 +000097 bool is_allowed_target_buffer(BufferID buffer_id) const {
98 return allowed_target_buffers_.count(buffer_id);
99 }
100
Eric Secklerf3f524b2018-12-13 09:09:34 +0000101 base::Optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
102 const auto it = writers_.find(writer_id);
103 if (it != writers_.end())
104 return it->second;
105 return base::nullopt;
106 }
107
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000108 private:
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100109 friend class TracingServiceImpl;
110 friend class TracingServiceImplTest;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000111 ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
112 ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
Primiano Tuccidca727d2018-04-04 11:31:55 +0200113 SharedMemoryArbiterImpl* GetOrCreateShmemArbiter();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000114
115 ProducerID const id_;
Sami Kyostila32e0b542018-02-14 08:55:43 +0000116 const uid_t uid_;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100117 TracingServiceImpl* const service_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000118 base::TaskRunner* const task_runner_;
119 Producer* producer_;
120 std::unique_ptr<SharedMemory> shared_memory_;
Isabelle Taylor69faa902018-03-21 15:42:03 +0000121 size_t shared_buffer_page_size_kb_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100122 SharedMemoryABI shmem_abi_;
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200123 size_t shmem_size_hint_bytes_ = 0;
Isabelle Taylor86262cb2018-03-27 16:00:54 +0100124 const std::string name_;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100125
Eric Seckler6dc23592018-11-30 10:59:06 +0000126 // Set of the global target_buffer IDs that the producer is configured to
127 // write into in any active tracing session.
128 std::set<BufferID> allowed_target_buffers_;
129
Eric Secklerf3f524b2018-12-13 09:09:34 +0000130 // Maps registered TraceWriter IDs to their target buffers as registered by
131 // the producer. Note that producers aren't required to register their
132 // writers, so we may see commits of chunks with WriterIDs that aren't
133 // contained in this map. However, if a producer does register a writer, the
134 // service will prevent the writer from writing into any other buffer than
135 // the one associated with it here. The BufferIDs stored in this map are
136 // untrusted, so need to be verified against |allowed_target_buffers_|
137 // before use.
138 std::map<WriterID, BufferID> writers_;
139
Primiano Tucci14219ff2019-02-27 12:41:05 +0100140 // This is used only in in-process configurations. The mutex protects
141 // concurrent construction of |inproc_shmem_arbiter_|.
142 // SharedMemoryArbiterImpl methods themselves are thread-safe.
143 std::mutex inproc_shmem_arbiter_mutex_;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100144 std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;
Primiano Tucci14219ff2019-02-27 12:41:05 +0100145
Florian Mayercd08ec62018-01-31 17:49:25 +0000146 PERFETTO_THREAD_CHECKER(thread_checker_)
Primiano Tuccidca727d2018-04-04 11:31:55 +0200147 base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_; // Keep last.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000148 };
149
Primiano Tucci42e2de12017-12-07 16:46:04 +0000150 // The implementation behind the service endpoint exposed to each consumer.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100151 class ConsumerEndpointImpl : public TracingService::ConsumerEndpoint {
Primiano Tucci42e2de12017-12-07 16:46:04 +0000152 public:
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100153 ConsumerEndpointImpl(TracingServiceImpl*,
154 base::TaskRunner*,
155 Consumer*,
156 uid_t uid);
Primiano Tucci42e2de12017-12-07 16:46:04 +0000157 ~ConsumerEndpointImpl() override;
158
Primiano Tuccidca727d2018-04-04 11:31:55 +0200159 void NotifyOnTracingDisabled();
Primiano Tucci42e2de12017-12-07 16:46:04 +0000160 base::WeakPtr<ConsumerEndpointImpl> GetWeakPtr();
161
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100162 // TracingService::ConsumerEndpoint implementation.
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100163 void EnableTracing(const TraceConfig&, base::ScopedFile) override;
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -0800164 void ChangeTraceConfig(const TraceConfig& cfg) override;
Primiano Tucci674076d2018-10-01 10:41:09 +0100165 void StartTracing() override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000166 void DisableTracing() override;
167 void ReadBuffers() override;
168 void FreeBuffers() override;
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100169 void Flush(uint32_t timeout_ms, FlushCallback) override;
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100170 void Detach(const std::string& key) override;
171 void Attach(const std::string& key) override;
Eric Secklereaf29ed2019-01-23 09:53:55 +0000172 void GetTraceStats() override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000173
174 private:
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100175 friend class TracingServiceImpl;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000176 ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
177 ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
178
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100179 base::TaskRunner* const task_runner_;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100180 TracingServiceImpl* const service_;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000181 Consumer* const consumer_;
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100182 uid_t const uid_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000183 TracingSessionID tracing_session_id_ = 0;
Florian Mayercd08ec62018-01-31 17:49:25 +0000184 PERFETTO_THREAD_CHECKER(thread_checker_)
Primiano Tuccidca727d2018-04-04 11:31:55 +0200185 base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_; // Keep last.
Primiano Tucci42e2de12017-12-07 16:46:04 +0000186 };
187
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100188 explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>,
189 base::TaskRunner*);
190 ~TracingServiceImpl() override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000191
Primiano Tucci42e2de12017-12-07 16:46:04 +0000192 // Called by ProducerEndpointImpl.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000193 void DisconnectProducer(ProducerID);
Primiano Tucci9daa4832018-03-28 23:28:17 +0100194 void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
195 void UnregisterDataSource(ProducerID, const std::string& name);
Primiano Tucci53589332017-12-19 11:31:13 +0100196 void CopyProducerPageIntoLogBuffer(ProducerID,
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000197 uid_t,
198 WriterID,
199 ChunkID,
Primiano Tucci53589332017-12-19 11:31:13 +0100200 BufferID,
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000201 uint16_t num_fragments,
202 uint8_t chunk_flags,
Eric Secklerb77b27e2018-12-17 11:42:52 +0000203 bool chunk_complete,
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000204 const uint8_t* src,
205 size_t size);
206 void ApplyChunkPatches(ProducerID,
207 const std::vector<CommitDataRequest::ChunkToPatch>&);
Primiano Tuccid52e6272018-04-06 19:06:53 +0200208 void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100209 void NotifyDataSourceStopped(ProducerID, const DataSourceInstanceID);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000210
Primiano Tucci42e2de12017-12-07 16:46:04 +0000211 // Called by ConsumerEndpointImpl.
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100212 bool DetachConsumer(ConsumerEndpointImpl*, const std::string& key);
213 bool AttachConsumer(ConsumerEndpointImpl*, const std::string& key);
Primiano Tucci42e2de12017-12-07 16:46:04 +0000214 void DisconnectConsumer(ConsumerEndpointImpl*);
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100215 bool EnableTracing(ConsumerEndpointImpl*,
216 const TraceConfig&,
217 base::ScopedFile);
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -0800218 void ChangeTraceConfig(ConsumerEndpointImpl*, const TraceConfig&);
219
Primiano Tucci674076d2018-10-01 10:41:09 +0100220 bool StartTracing(TracingSessionID);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100221 void DisableTracing(TracingSessionID, bool disable_immediately = false);
Primiano Tuccid52e6272018-04-06 19:06:53 +0200222 void Flush(TracingSessionID tsid,
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100223 uint32_t timeout_ms,
Primiano Tuccid52e6272018-04-06 19:06:53 +0200224 ConsumerEndpoint::FlushCallback);
225 void FlushAndDisableTracing(TracingSessionID);
Primiano Tucci20d441d2018-01-16 09:25:51 +0000226 void ReadBuffers(TracingSessionID, ConsumerEndpointImpl*);
227 void FreeBuffers(TracingSessionID);
Primiano Tucci42e2de12017-12-07 16:46:04 +0000228
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000229 // Service implementation.
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100230 std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000231 Producer*,
Sami Kyostila32e0b542018-02-14 08:55:43 +0000232 uid_t uid,
Isabelle Taylor86262cb2018-03-27 16:00:54 +0100233 const std::string& producer_name,
Isabelle Taylor69faa902018-03-21 15:42:03 +0000234 size_t shared_memory_size_hint_bytes = 0) override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000235
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100236 std::unique_ptr<TracingService::ConsumerEndpoint> ConnectConsumer(
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100237 Consumer*,
238 uid_t) override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000239
Eric Secklera01e28a2019-01-08 11:21:04 +0000240 void SetSMBScrapingEnabled(bool enabled) override {
241 smb_scraping_enabled_ = enabled;
242 }
243
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000244 // Exposed mainly for testing.
245 size_t num_producers() const { return producers_.size(); }
246 ProducerEndpointImpl* GetProducer(ProducerID) const;
247
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100248 uint32_t override_data_source_test_timeout_ms_for_testing = 0;
249
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000250 private:
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100251 friend class TracingServiceImplTest;
Primiano Tucci081d46a2018-02-28 11:09:43 +0000252
Primiano Tucci53589332017-12-19 11:31:13 +0100253 struct RegisteredDataSource {
254 ProducerID producer_id;
Primiano Tucci53589332017-12-19 11:31:13 +0100255 DataSourceDescriptor descriptor;
256 };
257
Sami Kyostila06487a22018-02-27 13:48:38 +0000258 // Represents an active data source for a tracing session.
259 struct DataSourceInstance {
Primiano Tucci5403e4f2018-11-27 10:07:03 +0000260 DataSourceInstance(DataSourceInstanceID id,
261 const DataSourceConfig& cfg,
262 const std::string& ds_name,
263 bool notify)
264 : instance_id(id),
265 config(cfg),
266 data_source_name(ds_name),
267 will_notify_on_stop(notify) {}
Primiano Tucci674076d2018-10-01 10:41:09 +0100268 DataSourceInstance(const DataSourceInstance&) = delete;
269 DataSourceInstance& operator=(const DataSourceInstance&) = delete;
Primiano Tucci674076d2018-10-01 10:41:09 +0100270
Sami Kyostila06487a22018-02-27 13:48:38 +0000271 DataSourceInstanceID instance_id;
Primiano Tucci674076d2018-10-01 10:41:09 +0100272 DataSourceConfig config;
Primiano Tucci9daa4832018-03-28 23:28:17 +0100273 std::string data_source_name;
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100274 bool will_notify_on_stop;
Sami Kyostila06487a22018-02-27 13:48:38 +0000275 };
276
Primiano Tuccid52e6272018-04-06 19:06:53 +0200277 struct PendingFlush {
278 std::set<ProducerID> producers;
279 ConsumerEndpoint::FlushCallback callback;
280 explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
281 };
282
Primiano Tucci53589332017-12-19 11:31:13 +0100283 // Holds the state of a tracing session. A tracing session is uniquely bound
284 // a specific Consumer. Each Consumer can own one or more sessions.
285 struct TracingSession {
Primiano Tucci674076d2018-10-01 10:41:09 +0100286 enum State {
287 DISABLED = 0,
288 CONFIGURED,
289 STARTED,
290 DISABLING_WAITING_STOP_ACKS
291 };
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100292
293 TracingSession(TracingSessionID, ConsumerEndpointImpl*, const TraceConfig&);
Primiano Tucci20d441d2018-01-16 09:25:51 +0000294
295 size_t num_buffers() const { return buffers_index.size(); }
296
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100297 uint32_t delay_to_next_write_period_ms() const {
Sami Kyostila01c45f02018-03-29 15:43:10 +0100298 PERFETTO_DCHECK(write_period_ms > 0);
299 return write_period_ms -
300 (base::GetWallTimeMs().count() % write_period_ms);
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100301 }
302
Florian Mayere563f662019-01-09 11:04:50 +0000303 uint32_t flush_timeout_ms() {
304 uint32_t timeout_ms = config.flush_timeout_ms();
305 return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs;
306 }
307
Eric Secklerd0ac7ca2019-02-06 09:13:45 +0000308 PacketSequenceID GetPacketSequenceID(ProducerID producer_id,
309 WriterID writer_id) {
310 auto key = std::make_pair(producer_id, writer_id);
311 auto it = packet_sequence_ids.find(key);
312 if (it != packet_sequence_ids.end())
313 return it->second;
314 // We shouldn't run out of sequence IDs (producer ID is 16 bit, writer IDs
315 // are limited to 1024).
316 static_assert(kMaxPacketSequenceID > kMaxProducerID * kMaxWriterID,
317 "PacketSequenceID value space doesn't cover service "
318 "sequence ID and all producer/writer ID combinations!");
319 PERFETTO_DCHECK(last_packet_sequence_id < kMaxPacketSequenceID);
320 PacketSequenceID sequence_id = ++last_packet_sequence_id;
321 packet_sequence_ids[key] = sequence_id;
322 return sequence_id;
323 }
324
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100325 const TracingSessionID id;
326
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100327 // The consumer that started the session.
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100328 // Can be nullptr if the consumer detached from the session.
329 ConsumerEndpointImpl* consumer_maybe_null;
330
331 // Unix uid of the consumer. This is valid even after the consumer detaches
332 // and does not change for the entire duration of the session. It is used to
333 // prevent that a consumer re-attaches to a session from a different uid.
334 uid_t const consumer_uid;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100335
Oystein Eftevaagcb6e4c82019-03-06 15:38:26 -0800336 // The trace config provided by the Consumer when calling
337 // EnableTracing(), plus any updates performed by ChangeTraceConfig.
338 TraceConfig config;
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -0800339
Primiano Tucci53589332017-12-19 11:31:13 +0100340 // List of data source instances that have been enabled on the various
341 // producers for this tracing session.
Sami Kyostila06487a22018-02-27 13:48:38 +0000342 std::multimap<ProducerID, DataSourceInstance> data_source_instances;
Primiano Tucci53589332017-12-19 11:31:13 +0100343
Primiano Tuccid52e6272018-04-06 19:06:53 +0200344 // For each Flush(N) request, keeps track of the set of producers for which
345 // we are still awaiting a NotifyFlushComplete(N) ack.
346 std::map<FlushRequestID, PendingFlush> pending_flushes;
347
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100348 // After DisableTracing() is called, this contains the subset of data
349 // sources that did set the |will_notify_on_stop| flag upon registration and
350 // that have the haven't replied yet to the stop request.
351 std::set<std::pair<ProducerID, DataSourceInstanceID>> pending_stop_acks;
352
Primiano Tucci20d441d2018-01-16 09:25:51 +0000353 // Maps a per-trace-session buffer index into the corresponding global
354 // BufferID (shared namespace amongst all consumers). This vector has as
355 // many entries as |config.buffers_size()|.
356 std::vector<BufferID> buffers_index;
Sami Kyostilafbccb3c2018-03-21 14:00:47 +0000357
Eric Secklerd0ac7ca2019-02-06 09:13:45 +0000358 std::map<std::pair<ProducerID, WriterID>, PacketSequenceID>
359 packet_sequence_ids;
360 PacketSequenceID last_packet_sequence_id = kServicePacketSequenceID;
361
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100362 // When the last snapshots (clock, stats, sync marker) were emitted into
363 // the output stream.
364 base::TimeMillis last_snapshot_time = {};
Primiano Tucci5e33cad2018-04-30 14:41:25 +0100365
Sami Kyostila200bd2e2018-03-26 12:24:10 +0100366 // Whether we mirrored the trace config back to the trace output yet.
367 bool did_emit_config = false;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100368
Hector Dearman685f7522019-03-12 14:28:56 +0000369 // Whether we put the system info into the trace output yet.
370 bool did_emit_system_info = false;
371
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100372 State state = DISABLED;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100373
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100374 // If the consumer detached the session, this variable defines the key used
375 // for identifying the session later when reattaching.
376 std::string detach_key;
377
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100378 // This is set when the Consumer calls sets |write_into_file| == true in the
379 // TraceConfig. In this case this represents the file we should stream the
380 // trace packets into, rather than returning it to the consumer via
381 // OnTraceData().
382 base::ScopedFile write_into_file;
Primiano Tucci3cbb10a2018-04-10 17:52:40 +0100383 uint32_t write_period_ms = 0;
384 uint64_t max_file_size_bytes = 0;
385 uint64_t bytes_written_into_file = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100386 };
387
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100388 TracingServiceImpl(const TracingServiceImpl&) = delete;
389 TracingServiceImpl& operator=(const TracingServiceImpl&) = delete;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000390
Primiano Tucci674076d2018-10-01 10:41:09 +0100391 DataSourceInstance* SetupDataSource(const TraceConfig::DataSource&,
392 const TraceConfig::ProducerConfig&,
393 const RegisteredDataSource&,
394 TracingSession*);
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -0800395
Primiano Tucci081d46a2018-02-28 11:09:43 +0000396 // Returns the next available ProducerID that is not in |producers_|.
397 ProducerID GetNextProducerID();
398
Primiano Tucci20d441d2018-01-16 09:25:51 +0000399 // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
400 // session doesn't exists.
401 TracingSession* GetTracingSession(TracingSessionID);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000402
Primiano Tucci9ba1d842018-12-20 17:31:04 +0100403 // Returns a pointer to the |tracing_sessions_| entry, matching the given
404 // uid and detach key, or nullptr if no such session exists.
405 TracingSession* GetDetachedSession(uid_t, const std::string& key);
406
Lalit Maganti485faff2018-03-06 11:51:35 +0000407 // Update the memory guard rail by using the latest information from the
408 // shared memory and trace buffers.
409 void UpdateMemoryGuardrail();
410
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100411 void SnapshotSyncMarker(std::vector<TracePacket>*);
412 void SnapshotClocks(std::vector<TracePacket>*);
413 void SnapshotStats(TracingSession*, std::vector<TracePacket>*);
Eric Secklereaf29ed2019-01-23 09:53:55 +0000414 TraceStats GetTraceStats(TracingSession* tracing_session);
Sami Kyostila200bd2e2018-03-26 12:24:10 +0100415 void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
Hector Dearman685f7522019-03-12 14:28:56 +0000416 void MaybeEmitSystemInfo(TracingSession*, std::vector<TracePacket>*);
Primiano Tuccid52e6272018-04-06 19:06:53 +0200417 void OnFlushTimeout(TracingSessionID, FlushRequestID);
Primiano Tuccibaeecf12018-07-25 12:02:20 +0100418 void OnDisableTracingTimeout(TracingSessionID);
419 void DisableTracingNotifyConsumerAndFlushFile(TracingSession*);
Primiano Tuccicaa57802018-11-25 11:07:07 +0000420 void PeriodicFlushTask(TracingSessionID, bool post_next_only);
Eric Secklera01e28a2019-01-08 11:21:04 +0000421 void CompleteFlush(TracingSessionID tsid,
422 ConsumerEndpoint::FlushCallback callback,
423 bool success);
424 void ScrapeSharedMemoryBuffers(TracingSession* tracing_session,
425 ProducerEndpointImpl* producer);
Hector Dearman6214c8f2018-03-27 16:16:22 +0100426 TraceBuffer* GetBufferByID(BufferID);
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000427
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000428 base::TaskRunner* const task_runner_;
Primiano Tucci53589332017-12-19 11:31:13 +0100429 std::unique_ptr<SharedMemory::Factory> shm_factory_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000430 ProducerID last_producer_id_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100431 DataSourceInstanceID last_data_source_instance_id_ = 0;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000432 TracingSessionID last_tracing_session_id_ = 0;
Primiano Tuccid52e6272018-04-06 19:06:53 +0200433 FlushRequestID last_flush_request_id_ = 0;
Primiano Tucci5e33cad2018-04-30 14:41:25 +0100434 uid_t uid_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100435
436 // Buffer IDs are global across all consumers (because a Producer can produce
437 // data for more than one trace session, hence more than one consumer).
Primiano Tucci20d441d2018-01-16 09:25:51 +0000438 IdAllocator<BufferID> buffer_ids_;
Primiano Tucci53589332017-12-19 11:31:13 +0100439
440 std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000441 std::map<ProducerID, ProducerEndpointImpl*> producers_;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000442 std::set<ConsumerEndpointImpl*> consumers_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000443 std::map<TracingSessionID, TracingSession> tracing_sessions_;
Hector Dearman6214c8f2018-03-27 16:16:22 +0100444 std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000445
Eric Secklera01e28a2019-01-08 11:21:04 +0000446 bool smb_scraping_enabled_ = false;
Florian Mayer61c55482018-03-06 14:43:54 +0000447 bool lockdown_mode_ = false;
Primiano Tucci9754d0d2018-09-15 12:41:46 +0100448 uint32_t min_write_period_ms_ = 100; // Overridable for testing.
449
450 uint8_t sync_marker_packet_[32]; // Lazily initialized.
451 size_t sync_marker_packet_size_ = 0;
Florian Mayer61c55482018-03-06 14:43:54 +0000452
Eric Seckler2c72bd82019-02-08 15:01:34 +0000453 // Stats.
454 uint64_t chunks_discarded_ = 0;
455 uint64_t patches_discarded_ = 0;
456
Florian Mayercd08ec62018-01-31 17:49:25 +0000457 PERFETTO_THREAD_CHECKER(thread_checker_)
458
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100459 base::WeakPtrFactory<TracingServiceImpl>
460 weak_ptr_factory_; // Keep at the end.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000461};
462
463} // namespace perfetto
464
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100465#endif // SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_