Home | History | Annotate | Download | only in trace_event
      1 // Copyright 2015 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_TRACE_EVENT_TRACE_LOG_H_
      6 #define BASE_TRACE_EVENT_TRACE_LOG_H_
      7 
      8 #include <stddef.h>
      9 #include <stdint.h>
     10 
     11 #include <string>
     12 #include <vector>
     13 
     14 #include "base/atomicops.h"
     15 #include "base/containers/hash_tables.h"
     16 #include "base/gtest_prod_util.h"
     17 #include "base/macros.h"
     18 #include "base/memory/scoped_ptr.h"
     19 #include "base/memory/scoped_vector.h"
     20 #include "base/trace_event/memory_dump_provider.h"
     21 #include "base/trace_event/trace_config.h"
     22 #include "base/trace_event/trace_event_impl.h"
     23 #include "build/build_config.h"
     24 
     25 namespace base {
     26 
     27 template <typename Type>
     28 struct DefaultSingletonTraits;
     29 class RefCountedString;
     30 
     31 namespace trace_event {
     32 
     33 class TraceBuffer;
     34 class TraceBufferChunk;
     35 class TraceEvent;
     36 class TraceEventMemoryOverhead;
     37 class TraceSamplingThread;
     38 
     39 struct BASE_EXPORT TraceLogStatus {
     40   TraceLogStatus();
     41   ~TraceLogStatus();
     42   size_t event_capacity;
     43   size_t event_count;
     44 };
     45 
     46 class BASE_EXPORT TraceLog : public MemoryDumpProvider {
     47  public:
     48   enum Mode {
     49     DISABLED = 0,
     50     RECORDING_MODE,
     51     MONITORING_MODE,
     52   };
     53 
     54   // The pointer returned from GetCategoryGroupEnabledInternal() points to a
     55   // value with zero or more of the following bits. Used in this class only.
     56   // The TRACE_EVENT macros should only use the value as a bool.
     57   // These values must be in sync with macro values in TraceEvent.h in Blink.
     58   enum CategoryGroupEnabledFlags {
     59     // Category group enabled for the recording mode.
     60     ENABLED_FOR_RECORDING = 1 << 0,
     61     // Category group enabled for the monitoring mode.
     62     ENABLED_FOR_MONITORING = 1 << 1,
     63     // Category group enabled by SetEventCallbackEnabled().
     64     ENABLED_FOR_EVENT_CALLBACK = 1 << 2,
     65     // Category group enabled to export events to ETW.
     66     ENABLED_FOR_ETW_EXPORT = 1 << 3
     67   };
     68 
     69   static TraceLog* GetInstance();
     70 
     71   // Get set of known category groups. This can change as new code paths are
     72   // reached. The known category groups are inserted into |category_groups|.
     73   void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
     74 
     75   // Retrieves a copy (for thread-safety) of the current TraceConfig.
     76   TraceConfig GetCurrentTraceConfig() const;
     77 
     78   // Initializes the thread-local event buffer, if not already initialized and
     79   // if the current thread supports that (has a message loop).
     80   void InitializeThreadLocalEventBufferIfSupported();
     81 
     82   // Enables normal tracing (recording trace events in the trace buffer).
     83   // See TraceConfig comments for details on how to control what categories
     84   // will be traced. If tracing has already been enabled, |category_filter| will
     85   // be merged into the current category filter.
     86   void SetEnabled(const TraceConfig& trace_config, Mode mode);
     87 
     88   // Disables normal tracing for all categories.
     89   void SetDisabled();
     90 
     91   bool IsEnabled() { return mode_ != DISABLED; }
     92 
     93   // The number of times we have begun recording traces. If tracing is off,
     94   // returns -1. If tracing is on, then it returns the number of times we have
     95   // recorded a trace. By watching for this number to increment, you can
     96   // passively discover when a new trace has begun. This is then used to
     97   // implement the TRACE_EVENT_IS_NEW_TRACE() primitive.
     98   int GetNumTracesRecorded();
     99 
    100 #if defined(OS_ANDROID)
    101   void StartATrace();
    102   void StopATrace();
    103   void AddClockSyncMetadataEvent();
    104 #endif
    105 
    106   // Enabled state listeners give a callback when tracing is enabled or
    107   // disabled. This can be used to tie into other library's tracing systems
    108   // on-demand.
    109   class BASE_EXPORT EnabledStateObserver {
    110    public:
    111     virtual ~EnabledStateObserver() = default;
    112 
    113     // Called just after the tracing system becomes enabled, outside of the
    114     // |lock_|. TraceLog::IsEnabled() is true at this point.
    115     virtual void OnTraceLogEnabled() = 0;
    116 
    117     // Called just after the tracing system disables, outside of the |lock_|.
    118     // TraceLog::IsEnabled() is false at this point.
    119     virtual void OnTraceLogDisabled() = 0;
    120   };
    121   void AddEnabledStateObserver(EnabledStateObserver* listener);
    122   void RemoveEnabledStateObserver(EnabledStateObserver* listener);
    123   bool HasEnabledStateObserver(EnabledStateObserver* listener) const;
    124 
    125   TraceLogStatus GetStatus() const;
    126   bool BufferIsFull() const;
    127 
    128   // Computes an estimate of the size of the TraceLog including all the retained
    129   // objects.
    130   void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
    131 
    132   // Not using base::Callback because of its limited by 7 parameters.
    133   // Also, using primitive type allows directly passing callback from WebCore.
    134   // WARNING: It is possible for the previously set callback to be called
    135   // after a call to SetEventCallbackEnabled() that replaces or a call to
    136   // SetEventCallbackDisabled() that disables the callback.
    137   // This callback may be invoked on any thread.
    138   // For TRACE_EVENT_PHASE_COMPLETE events, the client will still receive pairs
    139   // of TRACE_EVENT_PHASE_BEGIN and TRACE_EVENT_PHASE_END events to keep the
    140   // interface simple.
    141   typedef void (*EventCallback)(TimeTicks timestamp,
    142                                 char phase,
    143                                 const unsigned char* category_group_enabled,
    144                                 const char* name,
    145                                 unsigned long long id,
    146                                 int num_args,
    147                                 const char* const arg_names[],
    148                                 const unsigned char arg_types[],
    149                                 const unsigned long long arg_values[],
    150                                 unsigned int flags);
    151 
    152   // Enable tracing for EventCallback.
    153   void SetEventCallbackEnabled(const TraceConfig& trace_config,
    154                                EventCallback cb);
    155   void SetEventCallbackDisabled();
    156   void SetArgumentFilterPredicate(
    157       const ArgumentFilterPredicate& argument_filter_predicate);
    158 
    159   // Flush all collected events to the given output callback. The callback will
    160   // be called one or more times either synchronously or asynchronously from
    161   // the current thread with IPC-bite-size chunks. The string format is
    162   // undefined. Use TraceResultBuffer to convert one or more trace strings to
    163   // JSON. The callback can be null if the caller doesn't want any data.
    164   // Due to the implementation of thread-local buffers, flush can't be
    165   // done when tracing is enabled. If called when tracing is enabled, the
    166   // callback will be called directly with (empty_string, false) to indicate
    167   // the end of this unsuccessful flush. Flush does the serialization
    168   // on the same thread if the caller doesn't set use_worker_thread explicitly.
    169   typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&,
    170                               bool has_more_events)> OutputCallback;
    171   void Flush(const OutputCallback& cb, bool use_worker_thread = false);
    172   void FlushButLeaveBufferIntact(const OutputCallback& flush_output_callback);
    173 
    174   // Cancels tracing and discards collected data.
    175   void CancelTracing(const OutputCallback& cb);
    176 
    177   // Called by TRACE_EVENT* macros, don't call this directly.
    178   // The name parameter is a category group for example:
    179   // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
    180   static const unsigned char* GetCategoryGroupEnabled(const char* name);
    181   static const char* GetCategoryGroupName(
    182       const unsigned char* category_group_enabled);
    183 
    184   // Called by TRACE_EVENT* macros, don't call this directly.
    185   // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
    186   // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
    187   TraceEventHandle AddTraceEvent(
    188       char phase,
    189       const unsigned char* category_group_enabled,
    190       const char* name,
    191       unsigned long long id,
    192       int num_args,
    193       const char** arg_names,
    194       const unsigned char* arg_types,
    195       const unsigned long long* arg_values,
    196       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
    197       unsigned int flags);
    198   TraceEventHandle AddTraceEventWithBindId(
    199       char phase,
    200       const unsigned char* category_group_enabled,
    201       const char* name,
    202       unsigned long long id,
    203       unsigned long long bind_id,
    204       int num_args,
    205       const char** arg_names,
    206       const unsigned char* arg_types,
    207       const unsigned long long* arg_values,
    208       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
    209       unsigned int flags);
    210   TraceEventHandle AddTraceEventWithProcessId(
    211       char phase,
    212       const unsigned char* category_group_enabled,
    213       const char* name,
    214       unsigned long long id,
    215       int process_id,
    216       int num_args,
    217       const char** arg_names,
    218       const unsigned char* arg_types,
    219       const unsigned long long* arg_values,
    220       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
    221       unsigned int flags);
    222   TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
    223       char phase,
    224       const unsigned char* category_group_enabled,
    225       const char* name,
    226       unsigned long long id,
    227       int thread_id,
    228       const TimeTicks& timestamp,
    229       int num_args,
    230       const char** arg_names,
    231       const unsigned char* arg_types,
    232       const unsigned long long* arg_values,
    233       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
    234       unsigned int flags);
    235   TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
    236       char phase,
    237       const unsigned char* category_group_enabled,
    238       const char* name,
    239       unsigned long long id,
    240       unsigned long long bind_id,
    241       int thread_id,
    242       const TimeTicks& timestamp,
    243       int num_args,
    244       const char** arg_names,
    245       const unsigned char* arg_types,
    246       const unsigned long long* arg_values,
    247       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
    248       unsigned int flags);
    249 
    250   // Adds a metadata event that will be written when the trace log is flushed.
    251   void AddMetadataEvent(
    252       const char* name,
    253       int num_args,
    254       const char** arg_names,
    255       const unsigned char* arg_types,
    256       const unsigned long long* arg_values,
    257       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
    258       unsigned int flags);
    259 
    260   void UpdateTraceEventDuration(const unsigned char* category_group_enabled,
    261                                 const char* name,
    262                                 TraceEventHandle handle);
    263 
    264   // For every matching event, the callback will be called.
    265   typedef base::Callback<void()> WatchEventCallback;
    266   void SetWatchEvent(const std::string& category_name,
    267                      const std::string& event_name,
    268                      const WatchEventCallback& callback);
    269   // Cancel the watch event. If tracing is enabled, this may race with the
    270   // watch event notification firing.
    271   void CancelWatchEvent();
    272 
    273   int process_id() const { return process_id_; }
    274 
    275   uint64_t MangleEventId(uint64_t id);
    276 
    277   // Exposed for unittesting:
    278 
    279   void WaitSamplingEventForTesting();
    280 
    281   // Allows deleting our singleton instance.
    282   static void DeleteForTesting();
    283 
    284   // Allow tests to inspect TraceEvents.
    285   TraceEvent* GetEventByHandle(TraceEventHandle handle);
    286 
    287   void SetProcessID(int process_id);
    288 
    289   // Process sort indices, if set, override the order of a process will appear
    290   // relative to other processes in the trace viewer. Processes are sorted first
    291   // on their sort index, ascending, then by their name, and then tid.
    292   void SetProcessSortIndex(int sort_index);
    293 
    294   // Sets the name of the process.
    295   void SetProcessName(const std::string& process_name);
    296 
    297   // Processes can have labels in addition to their names. Use labels, for
    298   // instance, to list out the web page titles that a process is handling.
    299   void UpdateProcessLabel(int label_id, const std::string& current_label);
    300   void RemoveProcessLabel(int label_id);
    301 
    302   // Thread sort indices, if set, override the order of a thread will appear
    303   // within its process in the trace viewer. Threads are sorted first on their
    304   // sort index, ascending, then by their name, and then tid.
    305   void SetThreadSortIndex(PlatformThreadId thread_id, int sort_index);
    306 
    307   // Allow setting an offset between the current TimeTicks time and the time
    308   // that should be reported.
    309   void SetTimeOffset(TimeDelta offset);
    310 
    311   size_t GetObserverCountForTest() const;
    312 
    313   // Call this method if the current thread may block the message loop to
    314   // prevent the thread from using the thread-local buffer because the thread
    315   // may not handle the flush request in time causing lost of unflushed events.
    316   void SetCurrentThreadBlocksMessageLoop();
    317 
    318 #if defined(OS_WIN)
    319   // This function is called by the ETW exporting module whenever the ETW
    320   // keyword (flags) changes. This keyword indicates which categories should be
    321   // exported, so whenever it changes, we adjust accordingly.
    322   void UpdateETWCategoryGroupEnabledFlags();
    323 #endif
    324 
    325  private:
    326   typedef unsigned int InternalTraceOptions;
    327 
    328   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
    329                            TraceBufferRingBufferGetReturnChunk);
    330   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
    331                            TraceBufferRingBufferHalfIteration);
    332   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
    333                            TraceBufferRingBufferFullIteration);
    334   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, TraceBufferVectorReportFull);
    335   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
    336                            ConvertTraceConfigToInternalOptions);
    337   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
    338                            TraceRecordAsMuchAsPossibleMode);
    339 
    340   // This allows constructor and destructor to be private and usable only
    341   // by the Singleton class.
    342   friend struct DefaultSingletonTraits<TraceLog>;
    343 
    344   // MemoryDumpProvider implementation.
    345   bool OnMemoryDump(const MemoryDumpArgs& args,
    346                     ProcessMemoryDump* pmd) override;
    347 
    348   // Enable/disable each category group based on the current mode_,
    349   // category_filter_, event_callback_ and event_callback_category_filter_.
    350   // Enable the category group in the enabled mode if category_filter_ matches
    351   // the category group, or event_callback_ is not null and
    352   // event_callback_category_filter_ matches the category group.
    353   void UpdateCategoryGroupEnabledFlags();
    354   void UpdateCategoryGroupEnabledFlag(size_t category_index);
    355 
    356   // Configure synthetic delays based on the values set in the current
    357   // trace config.
    358   void UpdateSyntheticDelaysFromTraceConfig();
    359 
    360   InternalTraceOptions GetInternalOptionsFromTraceConfig(
    361       const TraceConfig& config);
    362 
    363   class ThreadLocalEventBuffer;
    364   class OptionalAutoLock;
    365 
    366   TraceLog();
    367   ~TraceLog() override;
    368   const unsigned char* GetCategoryGroupEnabledInternal(const char* name);
    369   void AddMetadataEventsWhileLocked();
    370 
    371   InternalTraceOptions trace_options() const {
    372     return static_cast<InternalTraceOptions>(
    373         subtle::NoBarrier_Load(&trace_options_));
    374   }
    375 
    376   TraceBuffer* trace_buffer() const { return logged_events_.get(); }
    377   TraceBuffer* CreateTraceBuffer();
    378 
    379   std::string EventToConsoleMessage(unsigned char phase,
    380                                     const TimeTicks& timestamp,
    381                                     TraceEvent* trace_event);
    382 
    383   TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle,
    384                                                      bool check_buffer_is_full);
    385   void CheckIfBufferIsFullWhileLocked();
    386   void SetDisabledWhileLocked();
    387 
    388   TraceEvent* GetEventByHandleInternal(TraceEventHandle handle,
    389                                        OptionalAutoLock* lock);
    390 
    391   void FlushInternal(const OutputCallback& cb,
    392                      bool use_worker_thread,
    393                      bool discard_events);
    394 
    395   // |generation| is used in the following callbacks to check if the callback
    396   // is called for the flush of the current |logged_events_|.
    397   void FlushCurrentThread(int generation, bool discard_events);
    398   // Usually it runs on a different thread.
    399   static void ConvertTraceEventsToTraceFormat(
    400       scoped_ptr<TraceBuffer> logged_events,
    401       const TraceLog::OutputCallback& flush_output_callback,
    402       const ArgumentFilterPredicate& argument_filter_predicate);
    403   void FinishFlush(int generation, bool discard_events);
    404   void OnFlushTimeout(int generation, bool discard_events);
    405 
    406   int generation() const {
    407     return static_cast<int>(subtle::NoBarrier_Load(&generation_));
    408   }
    409   bool CheckGeneration(int generation) const {
    410     return generation == this->generation();
    411   }
    412   void UseNextTraceBuffer();
    413 
    414   TimeTicks OffsetNow() const { return OffsetTimestamp(TimeTicks::Now()); }
    415   TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const {
    416     return timestamp - time_offset_;
    417   }
    418 
    419   // Internal representation of trace options since we store the currently used
    420   // trace option as an AtomicWord.
    421   static const InternalTraceOptions kInternalNone;
    422   static const InternalTraceOptions kInternalRecordUntilFull;
    423   static const InternalTraceOptions kInternalRecordContinuously;
    424   static const InternalTraceOptions kInternalEchoToConsole;
    425   static const InternalTraceOptions kInternalEnableSampling;
    426   static const InternalTraceOptions kInternalRecordAsMuchAsPossible;
    427   static const InternalTraceOptions kInternalEnableArgumentFilter;
    428 
    429   // This lock protects TraceLog member accesses (except for members protected
    430   // by thread_info_lock_) from arbitrary threads.
    431   mutable Lock lock_;
    432   // This lock protects accesses to thread_names_, thread_event_start_times_
    433   // and thread_colors_.
    434   Lock thread_info_lock_;
    435   Mode mode_;
    436   int num_traces_recorded_;
    437   scoped_ptr<TraceBuffer> logged_events_;
    438   std::vector<scoped_ptr<TraceEvent>> metadata_events_;
    439   subtle::AtomicWord /* EventCallback */ event_callback_;
    440   bool dispatching_to_observer_list_;
    441   std::vector<EnabledStateObserver*> enabled_state_observer_list_;
    442 
    443   std::string process_name_;
    444   base::hash_map<int, std::string> process_labels_;
    445   int process_sort_index_;
    446   base::hash_map<int, int> thread_sort_indices_;
    447   base::hash_map<int, std::string> thread_names_;
    448 
    449   // The following two maps are used only when ECHO_TO_CONSOLE.
    450   base::hash_map<int, std::stack<TimeTicks>> thread_event_start_times_;
    451   base::hash_map<std::string, int> thread_colors_;
    452 
    453   TimeTicks buffer_limit_reached_timestamp_;
    454 
    455   // XORed with TraceID to make it unlikely to collide with other processes.
    456   unsigned long long process_id_hash_;
    457 
    458   int process_id_;
    459 
    460   TimeDelta time_offset_;
    461 
    462   // Allow tests to wake up when certain events occur.
    463   WatchEventCallback watch_event_callback_;
    464   subtle::AtomicWord /* const unsigned char* */ watch_category_;
    465   std::string watch_event_name_;
    466 
    467   subtle::AtomicWord /* Options */ trace_options_;
    468 
    469   // Sampling thread handles.
    470   scoped_ptr<TraceSamplingThread> sampling_thread_;
    471   PlatformThreadHandle sampling_thread_handle_;
    472 
    473   TraceConfig trace_config_;
    474   TraceConfig event_callback_trace_config_;
    475 
    476   ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_;
    477   ThreadLocalBoolean thread_blocks_message_loop_;
    478   ThreadLocalBoolean thread_is_in_trace_event_;
    479 
    480   // Contains the message loops of threads that have had at least one event
    481   // added into the local event buffer. Not using SingleThreadTaskRunner
    482   // because we need to know the life time of the message loops.
    483   hash_set<MessageLoop*> thread_message_loops_;
    484 
    485   // For events which can't be added into the thread local buffer, e.g. events
    486   // from threads without a message loop.
    487   scoped_ptr<TraceBufferChunk> thread_shared_chunk_;
    488   size_t thread_shared_chunk_index_;
    489 
    490   // Set when asynchronous Flush is in progress.
    491   OutputCallback flush_output_callback_;
    492   scoped_refptr<SingleThreadTaskRunner> flush_task_runner_;
    493   ArgumentFilterPredicate argument_filter_predicate_;
    494   subtle::AtomicWord generation_;
    495   bool use_worker_thread_;
    496 
    497   DISALLOW_COPY_AND_ASSIGN(TraceLog);
    498 };
    499 
    500 }  // namespace trace_event
    501 }  // namespace base
    502 
    503 #endif  // BASE_TRACE_EVENT_TRACE_LOG_H_
    504