| // Copyright 2015 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef BASE_TRACE_EVENT_TRACE_LOG_H_ | 
 | #define BASE_TRACE_EVENT_TRACE_LOG_H_ | 
 |  | 
 | #include <stddef.h> | 
 | #include <stdint.h> | 
 |  | 
 | #include <memory> | 
 | #include <string> | 
 | #include <unordered_map> | 
 | #include <vector> | 
 |  | 
 | #include "base/atomicops.h" | 
 | #include "base/containers/stack.h" | 
 | #include "base/gtest_prod_util.h" | 
 | #include "base/macros.h" | 
 | #include "base/time/time_override.h" | 
 | #include "base/trace_event/memory_dump_provider.h" | 
 | #include "base/trace_event/trace_config.h" | 
 | #include "base/trace_event/trace_event_impl.h" | 
 | #include "build_config.h" | 
 |  | 
 | namespace base { | 
 |  | 
 | class MessageLoop; | 
 | class RefCountedString; | 
 |  | 
 | template <typename T> | 
 | class NoDestructor; | 
 |  | 
 | namespace trace_event { | 
 |  | 
 | struct TraceCategory; | 
 | class TraceBuffer; | 
 | class TraceBufferChunk; | 
 | class TraceEvent; | 
 | class TraceEventFilter; | 
 | class TraceEventMemoryOverhead; | 
 |  | 
 | struct BASE_EXPORT TraceLogStatus { | 
 |   TraceLogStatus(); | 
 |   ~TraceLogStatus(); | 
 |   uint32_t event_capacity; | 
 |   uint32_t event_count; | 
 | }; | 
 |  | 
 | class BASE_EXPORT TraceLog : public MemoryDumpProvider { | 
 |  public: | 
 |   // Argument passed to TraceLog::SetEnabled. | 
 |   enum Mode : uint8_t { | 
 |     // Enables normal tracing (recording trace events in the trace buffer). | 
 |     RECORDING_MODE = 1 << 0, | 
 |  | 
 |     // Trace events are enabled just for filtering but not for recording. Only | 
 |     // event filters config of |trace_config| argument is used. | 
 |     FILTERING_MODE = 1 << 1 | 
 |   }; | 
 |  | 
 |   static TraceLog* GetInstance(); | 
 |  | 
 |   // Get set of known category groups. This can change as new code paths are | 
 |   // reached. The known category groups are inserted into |category_groups|. | 
 |   void GetKnownCategoryGroups(std::vector<std::string>* category_groups); | 
 |  | 
 |   // Retrieves a copy (for thread-safety) of the current TraceConfig. | 
 |   TraceConfig GetCurrentTraceConfig() const; | 
 |  | 
 |   // Initializes the thread-local event buffer, if not already initialized and | 
 |   // if the current thread supports that (has a message loop). | 
 |   void InitializeThreadLocalEventBufferIfSupported(); | 
 |  | 
 |   // See TraceConfig comments for details on how to control which categories | 
 |   // will be traced. SetDisabled must be called distinctly for each mode that is | 
 |   // enabled. If tracing has already been enabled for recording, category filter | 
 |   // (enabled and disabled categories) will be merged into the current category | 
 |   // filter. Enabling RECORDING_MODE does not enable filters. Trace event | 
 |   // filters will be used only if FILTERING_MODE is set on |modes_to_enable|. | 
 |   // Conversely to RECORDING_MODE, FILTERING_MODE doesn't support upgrading, | 
 |   // i.e. filters can only be enabled if not previously enabled. | 
 |   void SetEnabled(const TraceConfig& trace_config, uint8_t modes_to_enable); | 
 |  | 
 |   // TODO(ssid): Remove the default SetEnabled and IsEnabled. They should take | 
 |   // Mode as argument. | 
 |  | 
 |   // Disables tracing for all categories for the specified |modes_to_disable| | 
 |   // only. Only RECORDING_MODE is taken as default |modes_to_disable|. | 
 |   void SetDisabled(); | 
 |   void SetDisabled(uint8_t modes_to_disable); | 
 |  | 
 |   // Returns true if TraceLog is enabled on recording mode. | 
 |   // Note: Returns false even if FILTERING_MODE is enabled. | 
 |   bool IsEnabled() { return enabled_modes_ & RECORDING_MODE; } | 
 |  | 
 |   // Returns a bitmap of enabled modes from TraceLog::Mode. | 
 |   uint8_t enabled_modes() { return enabled_modes_; } | 
 |  | 
 |   // The number of times we have begun recording traces. If tracing is off, | 
 |   // returns -1. If tracing is on, then it returns the number of times we have | 
 |   // recorded a trace. By watching for this number to increment, you can | 
 |   // passively discover when a new trace has begun. This is then used to | 
 |   // implement the TRACE_EVENT_IS_NEW_TRACE() primitive. | 
 |   int GetNumTracesRecorded(); | 
 |  | 
 | #if defined(OS_ANDROID) | 
 |   void StartATrace(); | 
 |   void StopATrace(); | 
 |   void AddClockSyncMetadataEvent(); | 
 | #endif | 
 |  | 
 |   // Enabled state listeners give a callback when tracing is enabled or | 
 |   // disabled. This can be used to tie into other library's tracing systems | 
 |   // on-demand. | 
 |   class BASE_EXPORT EnabledStateObserver { | 
 |    public: | 
 |     virtual ~EnabledStateObserver() = default; | 
 |  | 
 |     // Called just after the tracing system becomes enabled, outside of the | 
 |     // |lock_|. TraceLog::IsEnabled() is true at this point. | 
 |     virtual void OnTraceLogEnabled() = 0; | 
 |  | 
 |     // Called just after the tracing system disables, outside of the |lock_|. | 
 |     // TraceLog::IsEnabled() is false at this point. | 
 |     virtual void OnTraceLogDisabled() = 0; | 
 |   }; | 
 |   void AddEnabledStateObserver(EnabledStateObserver* listener); | 
 |   void RemoveEnabledStateObserver(EnabledStateObserver* listener); | 
 |   bool HasEnabledStateObserver(EnabledStateObserver* listener) const; | 
 |  | 
 |   // Asynchronous enabled state listeners. When tracing is enabled or disabled, | 
 |   // for each observer, a task for invoking its appropriate callback is posted | 
 |   // to the thread from which AddAsyncEnabledStateObserver() was called. This | 
 |   // allows the observer to be safely destroyed, provided that it happens on the | 
 |   // same thread that invoked AddAsyncEnabledStateObserver(). | 
 |   class BASE_EXPORT AsyncEnabledStateObserver { | 
 |    public: | 
 |     virtual ~AsyncEnabledStateObserver() = default; | 
 |  | 
 |     // Posted just after the tracing system becomes enabled, outside |lock_|. | 
 |     // TraceLog::IsEnabled() is true at this point. | 
 |     virtual void OnTraceLogEnabled() = 0; | 
 |  | 
 |     // Posted just after the tracing system becomes disabled, outside |lock_|. | 
 |     // TraceLog::IsEnabled() is false at this point. | 
 |     virtual void OnTraceLogDisabled() = 0; | 
 |   }; | 
 |   void AddAsyncEnabledStateObserver( | 
 |       WeakPtr<AsyncEnabledStateObserver> listener); | 
 |   void RemoveAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener); | 
 |   bool HasAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener) const; | 
 |  | 
 |   TraceLogStatus GetStatus() const; | 
 |   bool BufferIsFull() const; | 
 |  | 
 |   // Computes an estimate of the size of the TraceLog including all the retained | 
 |   // objects. | 
 |   void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); | 
 |  | 
 |   void SetArgumentFilterPredicate( | 
 |       const ArgumentFilterPredicate& argument_filter_predicate); | 
 |  | 
 |   // Flush all collected events to the given output callback. The callback will | 
 |   // be called one or more times either synchronously or asynchronously from | 
 |   // the current thread with IPC-bite-size chunks. The string format is | 
 |   // undefined. Use TraceResultBuffer to convert one or more trace strings to | 
 |   // JSON. The callback can be null if the caller doesn't want any data. | 
 |   // Due to the implementation of thread-local buffers, flush can't be | 
 |   // done when tracing is enabled. If called when tracing is enabled, the | 
 |   // callback will be called directly with (empty_string, false) to indicate | 
 |   // the end of this unsuccessful flush. Flush does the serialization | 
 |   // on the same thread if the caller doesn't set use_worker_thread explicitly. | 
 |   typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&, | 
 |                               bool has_more_events)> OutputCallback; | 
 |   void Flush(const OutputCallback& cb, bool use_worker_thread = false); | 
 |  | 
 |   // Cancels tracing and discards collected data. | 
 |   void CancelTracing(const OutputCallback& cb); | 
 |  | 
 |   typedef void (*AddTraceEventOverrideCallback)(const TraceEvent&); | 
 |   // The callback will be called up until the point where the flush is | 
 |   // finished, i.e. must be callable until OutputCallback is called with | 
 |   // has_more_events==false. | 
 |   void SetAddTraceEventOverride(const AddTraceEventOverrideCallback& override); | 
 |  | 
 |   // Called by TRACE_EVENT* macros, don't call this directly. | 
 |   // The name parameter is a category group for example: | 
 |   // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") | 
 |   static const unsigned char* GetCategoryGroupEnabled(const char* name); | 
 |   static const char* GetCategoryGroupName( | 
 |       const unsigned char* category_group_enabled); | 
 |  | 
 |   // Called by TRACE_EVENT* macros, don't call this directly. | 
 |   // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied | 
 |   // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. | 
 |   TraceEventHandle AddTraceEvent( | 
 |       char phase, | 
 |       const unsigned char* category_group_enabled, | 
 |       const char* name, | 
 |       const char* scope, | 
 |       unsigned long long id, | 
 |       int num_args, | 
 |       const char* const* arg_names, | 
 |       const unsigned char* arg_types, | 
 |       const unsigned long long* arg_values, | 
 |       std::unique_ptr<ConvertableToTraceFormat>* convertable_values, | 
 |       unsigned int flags); | 
 |   TraceEventHandle AddTraceEventWithBindId( | 
 |       char phase, | 
 |       const unsigned char* category_group_enabled, | 
 |       const char* name, | 
 |       const char* scope, | 
 |       unsigned long long id, | 
 |       unsigned long long bind_id, | 
 |       int num_args, | 
 |       const char* const* arg_names, | 
 |       const unsigned char* arg_types, | 
 |       const unsigned long long* arg_values, | 
 |       std::unique_ptr<ConvertableToTraceFormat>* convertable_values, | 
 |       unsigned int flags); | 
 |   TraceEventHandle AddTraceEventWithProcessId( | 
 |       char phase, | 
 |       const unsigned char* category_group_enabled, | 
 |       const char* name, | 
 |       const char* scope, | 
 |       unsigned long long id, | 
 |       int process_id, | 
 |       int num_args, | 
 |       const char* const* arg_names, | 
 |       const unsigned char* arg_types, | 
 |       const unsigned long long* arg_values, | 
 |       std::unique_ptr<ConvertableToTraceFormat>* convertable_values, | 
 |       unsigned int flags); | 
 |   TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( | 
 |       char phase, | 
 |       const unsigned char* category_group_enabled, | 
 |       const char* name, | 
 |       const char* scope, | 
 |       unsigned long long id, | 
 |       int thread_id, | 
 |       const TimeTicks& timestamp, | 
 |       int num_args, | 
 |       const char* const* arg_names, | 
 |       const unsigned char* arg_types, | 
 |       const unsigned long long* arg_values, | 
 |       std::unique_ptr<ConvertableToTraceFormat>* convertable_values, | 
 |       unsigned int flags); | 
 |   TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( | 
 |       char phase, | 
 |       const unsigned char* category_group_enabled, | 
 |       const char* name, | 
 |       const char* scope, | 
 |       unsigned long long id, | 
 |       unsigned long long bind_id, | 
 |       int thread_id, | 
 |       const TimeTicks& timestamp, | 
 |       int num_args, | 
 |       const char* const* arg_names, | 
 |       const unsigned char* arg_types, | 
 |       const unsigned long long* arg_values, | 
 |       std::unique_ptr<ConvertableToTraceFormat>* convertable_values, | 
 |       unsigned int flags); | 
 |  | 
 |   // Adds a metadata event that will be written when the trace log is flushed. | 
 |   void AddMetadataEvent( | 
 |       const unsigned char* category_group_enabled, | 
 |       const char* name, | 
 |       int num_args, | 
 |       const char* const* arg_names, | 
 |       const unsigned char* arg_types, | 
 |       const unsigned long long* arg_values, | 
 |       std::unique_ptr<ConvertableToTraceFormat>* convertable_values, | 
 |       unsigned int flags); | 
 |  | 
 |   void UpdateTraceEventDuration(const unsigned char* category_group_enabled, | 
 |                                 const char* name, | 
 |                                 TraceEventHandle handle); | 
 |  | 
 |   void UpdateTraceEventDurationExplicit( | 
 |       const unsigned char* category_group_enabled, | 
 |       const char* name, | 
 |       TraceEventHandle handle, | 
 |       const TimeTicks& now, | 
 |       const ThreadTicks& thread_now); | 
 |  | 
 |   void EndFilteredEvent(const unsigned char* category_group_enabled, | 
 |                         const char* name, | 
 |                         TraceEventHandle handle); | 
 |  | 
 |   int process_id() const { return process_id_; } | 
 |  | 
 |   uint64_t MangleEventId(uint64_t id); | 
 |  | 
 |   // Exposed for unittesting: | 
 |  | 
 |   // Testing factory for TraceEventFilter. | 
 |   typedef std::unique_ptr<TraceEventFilter> (*FilterFactoryForTesting)( | 
 |       const std::string& /* predicate_name */); | 
 |   void SetFilterFactoryForTesting(FilterFactoryForTesting factory) { | 
 |     filter_factory_for_testing_ = factory; | 
 |   } | 
 |  | 
 |   // Allows clearing up our singleton instance. | 
 |   static void ResetForTesting(); | 
 |  | 
 |   // Allow tests to inspect TraceEvents. | 
 |   TraceEvent* GetEventByHandle(TraceEventHandle handle); | 
 |  | 
 |   void SetProcessID(int process_id); | 
 |  | 
 |   // Process sort indices, if set, override the order of a process will appear | 
 |   // relative to other processes in the trace viewer. Processes are sorted first | 
 |   // on their sort index, ascending, then by their name, and then tid. | 
 |   void SetProcessSortIndex(int sort_index); | 
 |  | 
 |   // Sets the name of the process. | 
 |   void set_process_name(const std::string& process_name) { | 
 |     AutoLock lock(lock_); | 
 |     process_name_ = process_name; | 
 |   } | 
 |  | 
 |   bool IsProcessNameEmpty() const { return process_name_.empty(); } | 
 |  | 
 |   // Processes can have labels in addition to their names. Use labels, for | 
 |   // instance, to list out the web page titles that a process is handling. | 
 |   void UpdateProcessLabel(int label_id, const std::string& current_label); | 
 |   void RemoveProcessLabel(int label_id); | 
 |  | 
 |   // Thread sort indices, if set, override the order of a thread will appear | 
 |   // within its process in the trace viewer. Threads are sorted first on their | 
 |   // sort index, ascending, then by their name, and then tid. | 
 |   void SetThreadSortIndex(PlatformThreadId thread_id, int sort_index); | 
 |  | 
 |   // Allow setting an offset between the current TimeTicks time and the time | 
 |   // that should be reported. | 
 |   void SetTimeOffset(TimeDelta offset); | 
 |  | 
 |   size_t GetObserverCountForTest() const; | 
 |  | 
 |   // Call this method if the current thread may block the message loop to | 
 |   // prevent the thread from using the thread-local buffer because the thread | 
 |   // may not handle the flush request in time causing lost of unflushed events. | 
 |   void SetCurrentThreadBlocksMessageLoop(); | 
 |  | 
 | #if defined(OS_WIN) | 
 |   // This function is called by the ETW exporting module whenever the ETW | 
 |   // keyword (flags) changes. This keyword indicates which categories should be | 
 |   // exported, so whenever it changes, we adjust accordingly. | 
 |   void UpdateETWCategoryGroupEnabledFlags(); | 
 | #endif | 
 |  | 
 |   // Replaces |logged_events_| with a new TraceBuffer for testing. | 
 |   void SetTraceBufferForTesting(std::unique_ptr<TraceBuffer> trace_buffer); | 
 |  | 
 |  private: | 
 |   typedef unsigned int InternalTraceOptions; | 
 |  | 
 |   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | 
 |                            TraceBufferRingBufferGetReturnChunk); | 
 |   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | 
 |                            TraceBufferRingBufferHalfIteration); | 
 |   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | 
 |                            TraceBufferRingBufferFullIteration); | 
 |   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, TraceBufferVectorReportFull); | 
 |   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | 
 |                            ConvertTraceConfigToInternalOptions); | 
 |   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | 
 |                            TraceRecordAsMuchAsPossibleMode); | 
 |  | 
 |   friend class base::NoDestructor<TraceLog>; | 
 |  | 
 |   // MemoryDumpProvider implementation. | 
 |   bool OnMemoryDump(const MemoryDumpArgs& args, | 
 |                     ProcessMemoryDump* pmd) override; | 
 |  | 
 |   // Enable/disable each category group based on the current mode_, | 
 |   // category_filter_ and event_filters_enabled_. | 
 |   // Enable the category group in the recording mode if category_filter_ matches | 
 |   // the category group, is not null. Enable category for filtering if any | 
 |   // filter in event_filters_enabled_ enables it. | 
 |   void UpdateCategoryRegistry(); | 
 |   void UpdateCategoryState(TraceCategory* category); | 
 |  | 
 |   void CreateFiltersForTraceConfig(); | 
 |  | 
 |   InternalTraceOptions GetInternalOptionsFromTraceConfig( | 
 |       const TraceConfig& config); | 
 |  | 
 |   class ThreadLocalEventBuffer; | 
 |   class OptionalAutoLock; | 
 |   struct RegisteredAsyncObserver; | 
 |  | 
 |   TraceLog(); | 
 |   ~TraceLog() override; | 
 |   void AddMetadataEventsWhileLocked(); | 
 |  | 
 |   InternalTraceOptions trace_options() const { | 
 |     return static_cast<InternalTraceOptions>( | 
 |         subtle::NoBarrier_Load(&trace_options_)); | 
 |   } | 
 |  | 
 |   TraceBuffer* trace_buffer() const { return logged_events_.get(); } | 
 |   TraceBuffer* CreateTraceBuffer(); | 
 |  | 
 |   std::string EventToConsoleMessage(unsigned char phase, | 
 |                                     const TimeTicks& timestamp, | 
 |                                     TraceEvent* trace_event); | 
 |  | 
 |   TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle, | 
 |                                                      bool check_buffer_is_full); | 
 |   void CheckIfBufferIsFullWhileLocked(); | 
 |   void SetDisabledWhileLocked(uint8_t modes); | 
 |  | 
 |   TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, | 
 |                                        OptionalAutoLock* lock); | 
 |  | 
 |   void FlushInternal(const OutputCallback& cb, | 
 |                      bool use_worker_thread, | 
 |                      bool discard_events); | 
 |  | 
 |   // |generation| is used in the following callbacks to check if the callback | 
 |   // is called for the flush of the current |logged_events_|. | 
 |   void FlushCurrentThread(int generation, bool discard_events); | 
 |   // Usually it runs on a different thread. | 
 |   static void ConvertTraceEventsToTraceFormat( | 
 |       std::unique_ptr<TraceBuffer> logged_events, | 
 |       const TraceLog::OutputCallback& flush_output_callback, | 
 |       const ArgumentFilterPredicate& argument_filter_predicate); | 
 |   void FinishFlush(int generation, bool discard_events); | 
 |   void OnFlushTimeout(int generation, bool discard_events); | 
 |  | 
 |   int generation() const { | 
 |     return static_cast<int>(subtle::NoBarrier_Load(&generation_)); | 
 |   } | 
 |   bool CheckGeneration(int generation) const { | 
 |     return generation == this->generation(); | 
 |   } | 
 |   void UseNextTraceBuffer(); | 
 |  | 
 |   TimeTicks OffsetNow() const { | 
 |     // This should be TRACE_TIME_TICKS_NOW but include order makes that hard. | 
 |     return OffsetTimestamp(base::subtle::TimeTicksNowIgnoringOverride()); | 
 |   } | 
 |   TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const { | 
 |     return timestamp - time_offset_; | 
 |   } | 
 |  | 
 |   // Internal representation of trace options since we store the currently used | 
 |   // trace option as an AtomicWord. | 
 |   static const InternalTraceOptions kInternalNone; | 
 |   static const InternalTraceOptions kInternalRecordUntilFull; | 
 |   static const InternalTraceOptions kInternalRecordContinuously; | 
 |   static const InternalTraceOptions kInternalEchoToConsole; | 
 |   static const InternalTraceOptions kInternalRecordAsMuchAsPossible; | 
 |   static const InternalTraceOptions kInternalEnableArgumentFilter; | 
 |  | 
 |   // This lock protects TraceLog member accesses (except for members protected | 
 |   // by thread_info_lock_) from arbitrary threads. | 
 |   mutable Lock lock_; | 
 |   // This lock protects accesses to thread_names_, thread_event_start_times_ | 
 |   // and thread_colors_. | 
 |   Lock thread_info_lock_; | 
 |   uint8_t enabled_modes_;  // See TraceLog::Mode. | 
 |   int num_traces_recorded_; | 
 |   std::unique_ptr<TraceBuffer> logged_events_; | 
 |   std::vector<std::unique_ptr<TraceEvent>> metadata_events_; | 
 |   bool dispatching_to_observer_list_; | 
 |   std::vector<EnabledStateObserver*> enabled_state_observer_list_; | 
 |   std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> | 
 |       async_observers_; | 
 |  | 
 |   std::string process_name_; | 
 |   std::unordered_map<int, std::string> process_labels_; | 
 |   int process_sort_index_; | 
 |   std::unordered_map<int, int> thread_sort_indices_; | 
 |   std::unordered_map<int, std::string> thread_names_; | 
 |   base::Time process_creation_time_; | 
 |  | 
 |   // The following two maps are used only when ECHO_TO_CONSOLE. | 
 |   std::unordered_map<int, base::stack<TimeTicks>> thread_event_start_times_; | 
 |   std::unordered_map<std::string, int> thread_colors_; | 
 |  | 
 |   TimeTicks buffer_limit_reached_timestamp_; | 
 |  | 
 |   // XORed with TraceID to make it unlikely to collide with other processes. | 
 |   unsigned long long process_id_hash_; | 
 |  | 
 |   int process_id_; | 
 |  | 
 |   TimeDelta time_offset_; | 
 |  | 
 |   subtle::AtomicWord /* Options */ trace_options_; | 
 |  | 
 |   TraceConfig trace_config_; | 
 |   TraceConfig::EventFilters enabled_event_filters_; | 
 |  | 
 |   ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_; | 
 |   ThreadLocalBoolean thread_blocks_message_loop_; | 
 |   ThreadLocalBoolean thread_is_in_trace_event_; | 
 |  | 
 |   // Contains the message loops of threads that have had at least one event | 
 |   // added into the local event buffer. Not using SingleThreadTaskRunner | 
 |   // because we need to know the life time of the message loops. | 
 |   hash_set<MessageLoop*> thread_message_loops_; | 
 |  | 
 |   // For events which can't be added into the thread local buffer, e.g. events | 
 |   // from threads without a message loop. | 
 |   std::unique_ptr<TraceBufferChunk> thread_shared_chunk_; | 
 |   size_t thread_shared_chunk_index_; | 
 |  | 
 |   // Set when asynchronous Flush is in progress. | 
 |   OutputCallback flush_output_callback_; | 
 |   scoped_refptr<SingleThreadTaskRunner> flush_task_runner_; | 
 |   ArgumentFilterPredicate argument_filter_predicate_; | 
 |   subtle::AtomicWord generation_; | 
 |   bool use_worker_thread_; | 
 |   subtle::AtomicWord trace_event_override_; | 
 |  | 
 |   FilterFactoryForTesting filter_factory_for_testing_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(TraceLog); | 
 | }; | 
 |  | 
 | }  // namespace trace_event | 
 | }  // namespace base | 
 |  | 
 | #endif  // BASE_TRACE_EVENT_TRACE_LOG_H_ |