Home | History | Annotate | Download | only in core
      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 INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_H_
     18 #define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_H_
     19 
     20 #include <stdint.h>
     21 
     22 #include <functional>
     23 #include <memory>
     24 #include <vector>
     25 
     26 #include "perfetto/base/export.h"
     27 #include "perfetto/base/scoped_file.h"
     28 #include "perfetto/tracing/core/basic_types.h"
     29 #include "perfetto/tracing/core/shared_memory.h"
     30 
     31 namespace perfetto {
     32 
     33 namespace base {
     34 class TaskRunner;
     35 }  // namespace base
     36 
     37 class CommitDataRequest;
     38 class Consumer;
     39 class DataSourceDescriptor;
     40 class Producer;
     41 class SharedMemoryArbiter;
     42 class TraceConfig;
     43 class TraceWriter;
     44 
     45 // TODO: for the moment this assumes that all the calls happen on the same
     46 // thread/sequence. Not sure this will be the case long term in Chrome.
     47 
     48 // The API for the Producer port of the Service.
     49 // Subclassed by:
     50 // 1. The tracing_service_impl.cc business logic when returning it in response
     51 //    to the ConnectProducer() method.
     52 // 2. The transport layer (e.g., src/ipc) when the producer and
     53 //    the service don't talk locally but via some IPC mechanism.
     54 class PERFETTO_EXPORT ProducerEndpoint {
     55  public:
     56   virtual ~ProducerEndpoint();
     57 
     58   // Called by the Producer to (un)register data sources. Data sources are
     59   // identified by their name (i.e. DataSourceDescriptor.name)
     60   virtual void RegisterDataSource(const DataSourceDescriptor&) = 0;
     61   virtual void UnregisterDataSource(const std::string& name) = 0;
     62 
     63   // Associate the trace writer with the given |writer_id| with
     64   // |target_buffer|. The service may use this information to retrieve and
     65   // copy uncommitted chunks written by the trace writer into its associated
     66   // buffer, e.g. when a producer process crashes or when a flush is
     67   // necessary.
     68   virtual void RegisterTraceWriter(uint32_t writer_id,
     69                                    uint32_t target_buffer) = 0;
     70 
     71   // Remove the association of the trace writer previously created via
     72   // RegisterTraceWriter.
     73   virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;
     74 
     75   // Called by the Producer to signal that some pages in the shared memory
     76   // buffer (shared between Service and Producer) have changed.
     77   // When the Producer and the Service are hosted in the same process and
     78   // hence potentially live on the same task runner, This method must call
     79   // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
     80   // if on the same thread. This is to avoid a deadlock where the Producer
     81   // exhausts its SMB and stalls waiting for the service to catch up with
     82   // reads, but the Service never gets to that because it lives on the same
     83   // thread.
     84   using CommitDataCallback = std::function<void()>;
     85   virtual void CommitData(const CommitDataRequest&,
     86                           CommitDataCallback callback = {}) = 0;
     87 
     88   virtual SharedMemory* shared_memory() const = 0;
     89 
     90   // Size of shared memory buffer pages. It's always a multiple of 4K.
     91   // See shared_memory_abi.h
     92   virtual size_t shared_buffer_page_size_kb() const = 0;
     93 
     94   // Creates a trace writer, which allows to create events, handling the
     95   // underying shared memory buffer and signalling to the Service. This method
     96   // is thread-safe but the returned object is not. A TraceWriter should be
     97   // used only from a single thread, or the caller has to handle sequencing
     98   // via a mutex or equivalent. This method can only be called if
     99   // TracingService::ConnectProducer was called with |in_process=true|.
    100   // Args:
    101   // |target_buffer| is the target buffer ID where the data produced by the
    102   // writer should be stored by the tracing service. This value is passed
    103   // upon creation of the data source (StartDataSource()) in the
    104   // DataSourceConfig.target_buffer().
    105   virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
    106       BufferID target_buffer) = 0;
    107 
    108   // If TracingService::ConnectProducer is called with |in_process=true|,
    109   // this returns the producer's SharedMemoryArbiter which can be used
    110   // to create TraceWriters which is able to directly commit chunks
    111   // without going through an IPC layer.
    112   virtual SharedMemoryArbiter* GetInProcessShmemArbiter() = 0;
    113 
    114   // Called in response to a Producer::Flush(request_id) call after all data
    115   // for the flush request has been committed.
    116   virtual void NotifyFlushComplete(FlushRequestID) = 0;
    117 
    118   // Called in response to one or more Producer::StartDataSource(),
    119   // if the data source registered setting the flag
    120   // DataSourceDescriptor.will_notify_on_start.
    121   virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;
    122 
    123   // Called in response to one or more Producer::StopDataSource(),
    124   // if the data source registered setting the flag
    125   // DataSourceDescriptor.will_notify_on_stop.
    126   virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;
    127 
    128   // This informs the service to activate any of these triggers if any tracing
    129   // session was waiting for them.
    130   virtual void ActivateTriggers(const std::vector<std::string>&) = 0;
    131 };  // class ProducerEndpoint.
    132 
    133 // The API for the Consumer port of the Service.
    134 // Subclassed by:
    135 // 1. The tracing_service_impl.cc business logic when returning it in response
    136 // to
    137 //    the ConnectConsumer() method.
    138 // 2. The transport layer (e.g., src/ipc) when the consumer and
    139 //    the service don't talk locally but via some IPC mechanism.
    140 class ConsumerEndpoint {
    141  public:
    142   virtual ~ConsumerEndpoint();
    143 
    144   // Enables tracing with the given TraceConfig. The ScopedFile argument is
    145   // used only when TraceConfig.write_into_file == true.
    146   // If TraceConfig.deferred_start == true data sources are configured via
    147   // SetupDataSource() but are not started until StartTracing() is called.
    148   // This is to support pre-initialization and fast triggering of traces.
    149   // The ScopedFile argument is used only when TraceConfig.write_into_file
    150   // == true.
    151   virtual void EnableTracing(const TraceConfig&,
    152                              base::ScopedFile = base::ScopedFile()) = 0;
    153 
    154   // Update the trace config of an existing tracing session; only a subset
    155   // of options can be changed mid-session. Currently the only
    156   // supported functionality is expanding the list of producer_name_filters()
    157   // (or removing the filter entirely) for existing data sources.
    158   virtual void ChangeTraceConfig(const TraceConfig&) = 0;
    159 
    160   // Starts all data sources configured in the trace config. This is used only
    161   // after calling EnableTracing() with TraceConfig.deferred_start=true.
    162   // It's a no-op if called after a regular EnableTracing(), without setting
    163   // deferred_start.
    164   virtual void StartTracing() = 0;
    165 
    166   virtual void DisableTracing() = 0;
    167 
    168   // Requests all data sources to flush their data immediately and invokes the
    169   // passed callback once all of them have acked the flush (in which case
    170   // the callback argument |success| will be true) or |timeout_ms| are elapsed
    171   // (in which case |success| will be false).
    172   // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
    173   // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
    174   // used.
    175   using FlushCallback = std::function<void(bool /*success*/)>;
    176   virtual void Flush(uint32_t timeout_ms, FlushCallback) = 0;
    177 
    178   // Tracing data will be delivered invoking Consumer::OnTraceData().
    179   virtual void ReadBuffers() = 0;
    180 
    181   virtual void FreeBuffers() = 0;
    182 
    183   // Will call OnDetach().
    184   virtual void Detach(const std::string& key) = 0;
    185 
    186   // Will call OnAttach().
    187   virtual void Attach(const std::string& key) = 0;
    188 
    189   // Will call OnTraceStats().
    190   virtual void GetTraceStats() = 0;
    191 
    192   enum ObservableEventType : uint32_t {
    193     kNone = 0,
    194     kDataSourceInstances = 1 << 0
    195   };
    196 
    197   // Start or stop observing events of selected types. |enabled_event_types|
    198   // specifies the types of events to observe in a bitmask (see
    199   // ObservableEventType enum). To disable observing, pass
    200   // ObservableEventType::kNone. Will call OnObservableEvents() repeatedly
    201   // whenever an event of an enabled ObservableEventType occurs.
    202   //
    203   // TODO(eseckler): Extend this to support producers & data sources.
    204   virtual void ObserveEvents(uint32_t enabled_event_types) = 0;
    205 };  // class ConsumerEndpoint.
    206 
    207 // The public API of the tracing Service business logic.
    208 //
    209 // Exposed to:
    210 // 1. The transport layer (e.g., src/unix_rpc/unix_service_host.cc),
    211 //    which forwards commands received from a remote producer or consumer to
    212 //    the actual service implementation.
    213 // 2. Tests.
    214 //
    215 // Subclassed by:
    216 //   The service business logic in src/core/tracing_service_impl.cc.
    217 class PERFETTO_EXPORT TracingService {
    218  public:
    219   using ProducerEndpoint = perfetto::ProducerEndpoint;
    220   using ConsumerEndpoint = perfetto::ConsumerEndpoint;
    221 
    222   enum class ProducerSMBScrapingMode {
    223     // Use service's default setting for SMB scraping. Currently, the default
    224     // mode is to disable SMB scraping, but this may change in the future.
    225     kDefault,
    226 
    227     // Enable scraping of uncommitted chunks in producers' shared memory
    228     // buffers.
    229     kEnabled,
    230 
    231     // Disable scraping of uncommitted chunks in producers' shared memory
    232     // buffers.
    233     kDisabled
    234   };
    235 
    236   // Implemented in src/core/tracing_service_impl.cc .
    237   static std::unique_ptr<TracingService> CreateInstance(
    238       std::unique_ptr<SharedMemory::Factory>,
    239       base::TaskRunner*);
    240 
    241   virtual ~TracingService();
    242 
    243   // Connects a Producer instance and obtains a ProducerEndpoint, which is
    244   // essentially a 1:1 channel between one Producer and the Service.
    245   // The caller has to guarantee that the passed Producer will be alive as long
    246   // as the returned ProducerEndpoint is alive.
    247   // Both the passed Prodcer and the returned ProducerEndpint must live on the
    248   // same task runner of the service, specifically:
    249   // 1) The Service will call Producer::* methods on the Service's task runner.
    250   // 2) The Producer should call ProducerEndpoint::* methods only on the
    251   //    service's task runner, except for ProducerEndpoint::CreateTraceWriter(),
    252   //    which can be called on any thread.
    253   // To disconnect just destroy the returned ProducerEndpoint object. It is safe
    254   // to destroy the Producer once the Producer::OnDisconnect() has been invoked.
    255   // |uid| is the trusted user id of the producer process, used by the consumers
    256   // for validating the origin of trace data.
    257   // |shared_memory_size_hint_bytes| is an optional hint on the size of the
    258   // shared memory buffer. The service can ignore the hint (e.g., if the hint
    259   // is unreasonably large).
    260   // |in_process| enables the ProducerEndpoint to manage its own shared memory
    261   // and enables use of |ProducerEndpoint::CreateTraceWriter|.
    262   // Can return null in the unlikely event that service has too many producers
    263   // connected.
    264   virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
    265       Producer*,
    266       uid_t uid,
    267       const std::string& name,
    268       size_t shared_memory_size_hint_bytes = 0,
    269       bool in_process = false,
    270       ProducerSMBScrapingMode smb_scraping_mode =
    271           ProducerSMBScrapingMode::kDefault) = 0;
    272 
    273   // Connects a Consumer instance and obtains a ConsumerEndpoint, which is
    274   // essentially a 1:1 channel between one Consumer and the Service.
    275   // The caller has to guarantee that the passed Consumer will be alive as long
    276   // as the returned ConsumerEndpoint is alive.
    277   // To disconnect just destroy the returned ConsumerEndpoint object. It is safe
    278   // to destroy the Consumer once the Consumer::OnDisconnect() has been invoked.
    279   virtual std::unique_ptr<ConsumerEndpoint> ConnectConsumer(Consumer*,
    280                                                             uid_t) = 0;
    281 
    282   // Enable/disable scraping of chunks in the shared memory buffer. If enabled,
    283   // the service will copy uncommitted but non-empty chunks from the SMB when
    284   // flushing (e.g. to handle unresponsive producers or producers unable to
    285   // flush their active chunks), on producer disconnect (e.g. to recover data
    286   // from crashed producers), and after disabling a tracing session (e.g. to
    287   // gather data from producers that didn't stop their data sources in time).
    288   //
    289   // This feature is currently used by Chrome.
    290   virtual void SetSMBScrapingEnabled(bool enabled) = 0;
    291 };
    292 
    293 }  // namespace perfetto
    294 
    295 #endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_H_
    296