Home | History | Annotate | Download | only in debug
      1 // Copyright (c) 2012 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 
      6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_
      7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_
      8 
      9 #include <stack>
     10 #include <string>
     11 #include <vector>
     12 
     13 #include "base/atomicops.h"
     14 #include "base/callback.h"
     15 #include "base/containers/hash_tables.h"
     16 #include "base/gtest_prod_util.h"
     17 #include "base/memory/ref_counted_memory.h"
     18 #include "base/memory/scoped_vector.h"
     19 #include "base/observer_list.h"
     20 #include "base/strings/string_util.h"
     21 #include "base/synchronization/condition_variable.h"
     22 #include "base/synchronization/lock.h"
     23 #include "base/threading/thread.h"
     24 #include "base/threading/thread_local.h"
     25 #include "base/timer/timer.h"
     26 
     27 // Older style trace macros with explicit id and extra data
     28 // Only these macros result in publishing data to ETW as currently implemented.
     29 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \
     30     base::debug::TraceLog::AddTraceEventEtw( \
     31         TRACE_EVENT_PHASE_BEGIN, \
     32         name, reinterpret_cast<const void*>(id), extra)
     33 
     34 #define TRACE_EVENT_END_ETW(name, id, extra) \
     35     base::debug::TraceLog::AddTraceEventEtw( \
     36         TRACE_EVENT_PHASE_END, \
     37         name, reinterpret_cast<const void*>(id), extra)
     38 
     39 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \
     40     base::debug::TraceLog::AddTraceEventEtw( \
     41         TRACE_EVENT_PHASE_INSTANT, \
     42         name, reinterpret_cast<const void*>(id), extra)
     43 
     44 template <typename Type>
     45 struct DefaultSingletonTraits;
     46 
     47 #if defined(COMPILER_GCC)
     48 namespace BASE_HASH_NAMESPACE {
     49 template <>
     50 struct hash<base::MessageLoop*> {
     51   std::size_t operator()(base::MessageLoop* value) const {
     52     return reinterpret_cast<std::size_t>(value);
     53   }
     54 };
     55 }  // BASE_HASH_NAMESPACE
     56 #endif
     57 
     58 namespace base {
     59 
     60 class WaitableEvent;
     61 class MessageLoop;
     62 
     63 namespace debug {
     64 
     65 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
     66 // class must implement this interface.
     67 class ConvertableToTraceFormat : public RefCounted<ConvertableToTraceFormat> {
     68  public:
     69   // Append the class info to the provided |out| string. The appended
     70   // data must be a valid JSON object. Strings must be properly quoted, and
     71   // escaped. There is no processing applied to the content after it is
     72   // appended.
     73   virtual void AppendAsTraceFormat(std::string* out) const = 0;
     74 
     75  protected:
     76   virtual ~ConvertableToTraceFormat() {}
     77 
     78  private:
     79   friend class RefCounted<ConvertableToTraceFormat>;
     80 };
     81 
     82 struct TraceEventHandle {
     83   uint32 chunk_seq;
     84   uint16 chunk_index;
     85   uint16 event_index;
     86 };
     87 
     88 const int kTraceMaxNumArgs = 2;
     89 
     90 class BASE_EXPORT TraceEvent {
     91  public:
     92   union TraceValue {
     93     bool as_bool;
     94     unsigned long long as_uint;
     95     long long as_int;
     96     double as_double;
     97     const void* as_pointer;
     98     const char* as_string;
     99   };
    100 
    101   TraceEvent();
    102   ~TraceEvent();
    103 
    104   // We don't need to copy TraceEvent except when TraceEventBuffer is cloned.
    105   // Use explicit copy method to avoid accidentally misuse of copy.
    106   void CopyFrom(const TraceEvent& other);
    107 
    108   void Initialize(
    109       int thread_id,
    110       TimeTicks timestamp,
    111       TimeTicks thread_timestamp,
    112       char phase,
    113       const unsigned char* category_group_enabled,
    114       const char* name,
    115       unsigned long long id,
    116       int num_args,
    117       const char** arg_names,
    118       const unsigned char* arg_types,
    119       const unsigned long long* arg_values,
    120       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
    121       unsigned char flags);
    122 
    123   void Reset();
    124 
    125   void UpdateDuration(const TimeTicks& now, const TimeTicks& thread_now);
    126 
    127   // Serialize event data to JSON
    128   static void AppendEventsAsJSON(const std::vector<TraceEvent>& events,
    129                                  size_t start,
    130                                  size_t count,
    131                                  std::string* out);
    132   void AppendAsJSON(std::string* out) const;
    133   void AppendPrettyPrinted(std::ostringstream* out) const;
    134 
    135   static void AppendValueAsJSON(unsigned char type,
    136                                 TraceValue value,
    137                                 std::string* out);
    138 
    139   TimeTicks timestamp() const { return timestamp_; }
    140   TimeTicks thread_timestamp() const { return thread_timestamp_; }
    141   char phase() const { return phase_; }
    142   int thread_id() const { return thread_id_; }
    143   TimeDelta duration() const { return duration_; }
    144   TimeDelta thread_duration() const { return thread_duration_; }
    145   unsigned long long id() const { return id_; }
    146   unsigned char flags() const { return flags_; }
    147 
    148   // Exposed for unittesting:
    149 
    150   const base::RefCountedString* parameter_copy_storage() const {
    151     return parameter_copy_storage_.get();
    152   }
    153 
    154   const unsigned char* category_group_enabled() const {
    155     return category_group_enabled_;
    156   }
    157 
    158   const char* name() const { return name_; }
    159 
    160 #if defined(OS_ANDROID)
    161   void SendToATrace();
    162 #endif
    163 
    164  private:
    165   // Note: these are ordered by size (largest first) for optimal packing.
    166   TimeTicks timestamp_;
    167   TimeTicks thread_timestamp_;
    168   TimeDelta duration_;
    169   TimeDelta thread_duration_;
    170   // id_ can be used to store phase-specific data.
    171   unsigned long long id_;
    172   TraceValue arg_values_[kTraceMaxNumArgs];
    173   const char* arg_names_[kTraceMaxNumArgs];
    174   scoped_refptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs];
    175   const unsigned char* category_group_enabled_;
    176   const char* name_;
    177   scoped_refptr<base::RefCountedString> parameter_copy_storage_;
    178   int thread_id_;
    179   char phase_;
    180   unsigned char flags_;
    181   unsigned char arg_types_[kTraceMaxNumArgs];
    182 
    183   DISALLOW_COPY_AND_ASSIGN(TraceEvent);
    184 };
    185 
    186 // TraceBufferChunk is the basic unit of TraceBuffer.
    187 class BASE_EXPORT TraceBufferChunk {
    188  public:
    189   TraceBufferChunk(uint32 seq)
    190       : next_free_(0),
    191         seq_(seq) {
    192   }
    193 
    194   void Reset(uint32 new_seq);
    195   TraceEvent* AddTraceEvent(size_t* event_index);
    196   bool IsFull() const { return next_free_ == kTraceBufferChunkSize; }
    197 
    198   uint32 seq() const { return seq_; }
    199   size_t capacity() const { return kTraceBufferChunkSize; }
    200   size_t size() const { return next_free_; }
    201 
    202   TraceEvent* GetEventAt(size_t index) {
    203     DCHECK(index < size());
    204     return &chunk_[index];
    205   }
    206   const TraceEvent* GetEventAt(size_t index) const {
    207     DCHECK(index < size());
    208     return &chunk_[index];
    209   }
    210 
    211   scoped_ptr<TraceBufferChunk> Clone() const;
    212 
    213   static const size_t kTraceBufferChunkSize = 64;
    214 
    215  private:
    216   size_t next_free_;
    217   TraceEvent chunk_[kTraceBufferChunkSize];
    218   uint32 seq_;
    219 };
    220 
    221 // TraceBuffer holds the events as they are collected.
    222 class BASE_EXPORT TraceBuffer {
    223  public:
    224   virtual ~TraceBuffer() {}
    225 
    226   virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t *index) = 0;
    227   virtual void ReturnChunk(size_t index,
    228                            scoped_ptr<TraceBufferChunk> chunk) = 0;
    229 
    230   virtual bool IsFull() const = 0;
    231   virtual size_t Size() const = 0;
    232   virtual size_t Capacity() const = 0;
    233   virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) = 0;
    234 
    235   // For iteration. Each TraceBuffer can only be iterated once.
    236   virtual const TraceBufferChunk* NextChunk() = 0;
    237 
    238   virtual scoped_ptr<TraceBuffer> CloneForIteration() const = 0;
    239 };
    240 
    241 // TraceResultBuffer collects and converts trace fragments returned by TraceLog
    242 // to JSON output.
    243 class BASE_EXPORT TraceResultBuffer {
    244  public:
    245   typedef base::Callback<void(const std::string&)> OutputCallback;
    246 
    247   // If you don't need to stream JSON chunks out efficiently, and just want to
    248   // get a complete JSON string after calling Finish, use this struct to collect
    249   // JSON trace output.
    250   struct BASE_EXPORT SimpleOutput {
    251     OutputCallback GetCallback();
    252     void Append(const std::string& json_string);
    253 
    254     // Do what you want with the json_output_ string after calling
    255     // TraceResultBuffer::Finish.
    256     std::string json_output;
    257   };
    258 
    259   TraceResultBuffer();
    260   ~TraceResultBuffer();
    261 
    262   // Set callback. The callback will be called during Start with the initial
    263   // JSON output and during AddFragment and Finish with following JSON output
    264   // chunks. The callback target must live past the last calls to
    265   // TraceResultBuffer::Start/AddFragment/Finish.
    266   void SetOutputCallback(const OutputCallback& json_chunk_callback);
    267 
    268   // Start JSON output. This resets all internal state, so you can reuse
    269   // the TraceResultBuffer by calling Start.
    270   void Start();
    271 
    272   // Call AddFragment 0 or more times to add trace fragments from TraceLog.
    273   void AddFragment(const std::string& trace_fragment);
    274 
    275   // When all fragments have been added, call Finish to complete the JSON
    276   // formatted output.
    277   void Finish();
    278 
    279  private:
    280   OutputCallback output_callback_;
    281   bool append_comma_;
    282 };
    283 
    284 class BASE_EXPORT CategoryFilter {
    285  public:
    286   // The default category filter, used when none is provided.
    287   // Allows all categories through, except if they end in the suffix 'Debug' or
    288   // 'Test'.
    289   static const char* kDefaultCategoryFilterString;
    290 
    291   // |filter_string| is a comma-delimited list of category wildcards.
    292   // A category can have an optional '-' prefix to make it an excluded category.
    293   // All the same rules apply above, so for example, having both included and
    294   // excluded categories in the same list would not be supported.
    295   //
    296   // Example: CategoryFilter"test_MyTest*");
    297   // Example: CategoryFilter("test_MyTest*,test_OtherStuff");
    298   // Example: CategoryFilter("-excluded_category1,-excluded_category2");
    299   // Example: CategoryFilter("-*,webkit"); would disable everything but webkit.
    300   // Example: CategoryFilter("-webkit"); would enable everything but webkit.
    301   explicit CategoryFilter(const std::string& filter_string);
    302 
    303   CategoryFilter(const CategoryFilter& cf);
    304 
    305   ~CategoryFilter();
    306 
    307   CategoryFilter& operator=(const CategoryFilter& rhs);
    308 
    309   // Writes the string representation of the CategoryFilter. This is a comma
    310   // separated string, similar in nature to the one used to determine
    311   // enabled/disabled category patterns, except here there is an arbitrary
    312   // order, included categories go first, then excluded categories. Excluded
    313   // categories are distinguished from included categories by the prefix '-'.
    314   std::string ToString() const;
    315 
    316   // Determines whether category group would be enabled or
    317   // disabled by this category filter.
    318   bool IsCategoryGroupEnabled(const char* category_group) const;
    319 
    320   // Merges nested_filter with the current CategoryFilter
    321   void Merge(const CategoryFilter& nested_filter);
    322 
    323   // Clears both included/excluded pattern lists. This would be equivalent to
    324   // creating a CategoryFilter with an empty string, through the constructor.
    325   // i.e: CategoryFilter("").
    326   //
    327   // When using an empty filter, all categories are considered included as we
    328   // are not excluding anything.
    329   void Clear();
    330 
    331  private:
    332   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, CategoryFilter);
    333 
    334   static bool IsEmptyOrContainsLeadingOrTrailingWhitespace(
    335       const std::string& str);
    336 
    337   typedef std::vector<std::string> StringList;
    338 
    339   void Initialize(const std::string& filter_string);
    340   void WriteString(const StringList& values,
    341                    std::string* out,
    342                    bool included) const;
    343   bool HasIncludedPatterns() const;
    344 
    345   bool DoesCategoryGroupContainCategory(const char* category_group,
    346                                         const char* category) const;
    347 
    348   StringList included_;
    349   StringList disabled_;
    350   StringList excluded_;
    351 };
    352 
    353 class TraceSamplingThread;
    354 
    355 class BASE_EXPORT TraceLog {
    356  public:
    357   // Options determines how the trace buffer stores data.
    358   enum Options {
    359     // Record until the trace buffer is full.
    360     RECORD_UNTIL_FULL = 1 << 0,
    361 
    362     // Record until the user ends the trace. The trace buffer is a fixed size
    363     // and we use it as a ring buffer during recording.
    364     RECORD_CONTINUOUSLY = 1 << 1,
    365 
    366     // Enable the sampling profiler in the recording mode.
    367     ENABLE_SAMPLING = 1 << 2,
    368 
    369     // Enable the sampling profiler in the monitoring mode.
    370     MONITOR_SAMPLING = 1 << 3,
    371 
    372     // Echo to console. Events are discarded.
    373     ECHO_TO_CONSOLE = 1 << 4,
    374   };
    375 
    376   // The pointer returned from GetCategoryGroupEnabledInternal() points to a
    377   // value with zero or more of the following bits. Used in this class only.
    378   // The TRACE_EVENT macros should only use the value as a bool.
    379   enum CategoryGroupEnabledFlags {
    380     // Normal enabled flag for category groups enabled by SetEnabled().
    381     ENABLED_FOR_RECORDING = 1 << 0,
    382     // Category group enabled by SetEventCallbackEnabled().
    383     ENABLED_FOR_EVENT_CALLBACK = 1 << 1,
    384   };
    385 
    386   static TraceLog* GetInstance();
    387 
    388   // Get set of known category groups. This can change as new code paths are
    389   // reached. The known category groups are inserted into |category_groups|.
    390   void GetKnownCategoryGroups(std::vector<std::string>* category_groups);
    391 
    392   // Retrieves a copy (for thread-safety) of the current CategoryFilter.
    393   CategoryFilter GetCurrentCategoryFilter();
    394 
    395   Options trace_options() const {
    396     return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_));
    397   }
    398 
    399   // Enables normal tracing (recording trace events in the trace buffer).
    400   // See CategoryFilter comments for details on how to control what categories
    401   // will be traced. If tracing has already been enabled, |category_filter| will
    402   // be merged into the current category filter.
    403   void SetEnabled(const CategoryFilter& category_filter, Options options);
    404 
    405   // Disables normal tracing for all categories.
    406   void SetDisabled();
    407 
    408   bool IsEnabled() { return enabled_; }
    409 
    410   // The number of times we have begun recording traces. If tracing is off,
    411   // returns -1. If tracing is on, then it returns the number of times we have
    412   // recorded a trace. By watching for this number to increment, you can
    413   // passively discover when a new trace has begun. This is then used to
    414   // implement the TRACE_EVENT_IS_NEW_TRACE() primitive.
    415   int GetNumTracesRecorded();
    416 
    417 #if defined(OS_ANDROID)
    418   void StartATrace();
    419   void StopATrace();
    420   void AddClockSyncMetadataEvent();
    421 #endif
    422 
    423   // Enabled state listeners give a callback when tracing is enabled or
    424   // disabled. This can be used to tie into other library's tracing systems
    425   // on-demand.
    426   class EnabledStateObserver {
    427    public:
    428     // Called just after the tracing system becomes enabled, outside of the
    429     // |lock_|.  TraceLog::IsEnabled() is true at this point.
    430     virtual void OnTraceLogEnabled() = 0;
    431 
    432     // Called just after the tracing system disables, outside of the |lock_|.
    433     // TraceLog::IsEnabled() is false at this point.
    434     virtual void OnTraceLogDisabled() = 0;
    435   };
    436   void AddEnabledStateObserver(EnabledStateObserver* listener);
    437   void RemoveEnabledStateObserver(EnabledStateObserver* listener);
    438   bool HasEnabledStateObserver(EnabledStateObserver* listener) const;
    439 
    440   float GetBufferPercentFull() const;
    441   bool BufferIsFull() const;
    442 
    443   // Not using base::Callback because of its limited by 7 parameters.
    444   // Also, using primitive type allows directly passing callback from WebCore.
    445   // WARNING: It is possible for the previously set callback to be called
    446   // after a call to SetEventCallbackEnabled() that replaces or a call to
    447   // SetEventCallbackDisabled() that disables the callback.
    448   // This callback may be invoked on any thread.
    449   // For TRACE_EVENT_PHASE_COMPLETE events, the client will still receive pairs
    450   // of TRACE_EVENT_PHASE_BEGIN and TRACE_EVENT_PHASE_END events to keep the
    451   // interface simple.
    452   typedef void (*EventCallback)(TimeTicks timestamp,
    453                                 char phase,
    454                                 const unsigned char* category_group_enabled,
    455                                 const char* name,
    456                                 unsigned long long id,
    457                                 int num_args,
    458                                 const char* const arg_names[],
    459                                 const unsigned char arg_types[],
    460                                 const unsigned long long arg_values[],
    461                                 unsigned char flags);
    462 
    463   // Enable tracing for EventCallback.
    464   void SetEventCallbackEnabled(const CategoryFilter& category_filter,
    465                                EventCallback cb);
    466   void SetEventCallbackDisabled();
    467 
    468   // Flush all collected events to the given output callback. The callback will
    469   // be called one or more times either synchronously or asynchronously from
    470   // the current thread with IPC-bite-size chunks. The string format is
    471   // undefined. Use TraceResultBuffer to convert one or more trace strings to
    472   // JSON. The callback can be null if the caller doesn't want any data.
    473   // Due to the implementation of thread-local buffers, flush can't be
    474   // done when tracing is enabled. If called when tracing is enabled, the
    475   // callback will be called directly with (empty_string, false) to indicate
    476   // the end of this unsuccessful flush.
    477   typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&,
    478                               bool has_more_events)> OutputCallback;
    479   void Flush(const OutputCallback& cb);
    480   void FlushButLeaveBufferIntact(const OutputCallback& flush_output_callback);
    481 
    482   // Called by TRACE_EVENT* macros, don't call this directly.
    483   // The name parameter is a category group for example:
    484   // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
    485   static const unsigned char* GetCategoryGroupEnabled(const char* name);
    486   static const char* GetCategoryGroupName(
    487       const unsigned char* category_group_enabled);
    488 
    489   // Called by TRACE_EVENT* macros, don't call this directly.
    490   // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied
    491   // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above.
    492   TraceEventHandle AddTraceEvent(
    493       char phase,
    494       const unsigned char* category_group_enabled,
    495       const char* name,
    496       unsigned long long id,
    497       int num_args,
    498       const char** arg_names,
    499       const unsigned char* arg_types,
    500       const unsigned long long* arg_values,
    501       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
    502       unsigned char flags);
    503   TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
    504       char phase,
    505       const unsigned char* category_group_enabled,
    506       const char* name,
    507       unsigned long long id,
    508       int thread_id,
    509       const TimeTicks& timestamp,
    510       int num_args,
    511       const char** arg_names,
    512       const unsigned char* arg_types,
    513       const unsigned long long* arg_values,
    514       const scoped_refptr<ConvertableToTraceFormat>* convertable_values,
    515       unsigned char flags);
    516   static void AddTraceEventEtw(char phase,
    517                                const char* category_group,
    518                                const void* id,
    519                                const char* extra);
    520   static void AddTraceEventEtw(char phase,
    521                                const char* category_group,
    522                                const void* id,
    523                                const std::string& extra);
    524 
    525   void UpdateTraceEventDuration(const unsigned char* category_group_enabled,
    526                                 const char* name,
    527                                 TraceEventHandle handle);
    528 
    529   // For every matching event, the callback will be called.
    530   typedef base::Callback<void()> WatchEventCallback;
    531   void SetWatchEvent(const std::string& category_name,
    532                      const std::string& event_name,
    533                      const WatchEventCallback& callback);
    534   // Cancel the watch event. If tracing is enabled, this may race with the
    535   // watch event notification firing.
    536   void CancelWatchEvent();
    537 
    538   int process_id() const { return process_id_; }
    539 
    540   // Exposed for unittesting:
    541 
    542   void WaitSamplingEventForTesting();
    543 
    544   // Allows deleting our singleton instance.
    545   static void DeleteForTesting();
    546 
    547   // Allow tests to inspect TraceEvents.
    548   size_t GetEventsSize() const { return logged_events_->Size(); }
    549   TraceEvent* GetEventByHandle(TraceEventHandle handle);
    550 
    551   void SetProcessID(int process_id);
    552 
    553   // Process sort indices, if set, override the order of a process will appear
    554   // relative to other processes in the trace viewer. Processes are sorted first
    555   // on their sort index, ascending, then by their name, and then tid.
    556   void SetProcessSortIndex(int sort_index);
    557 
    558   // Sets the name of the process.
    559   void SetProcessName(const std::string& process_name);
    560 
    561   // Processes can have labels in addition to their names. Use labels, for
    562   // instance, to list out the web page titles that a process is handling.
    563   void UpdateProcessLabel(int label_id, const std::string& current_label);
    564   void RemoveProcessLabel(int label_id);
    565 
    566   // Thread sort indices, if set, override the order of a thread will appear
    567   // within its process in the trace viewer. Threads are sorted first on their
    568   // sort index, ascending, then by their name, and then tid.
    569   void SetThreadSortIndex(PlatformThreadId , int sort_index);
    570 
    571   // Allow setting an offset between the current TimeTicks time and the time
    572   // that should be reported.
    573   void SetTimeOffset(TimeDelta offset);
    574 
    575   size_t GetObserverCountForTest() const;
    576 
    577   // Call this method if the current thread may block the message loop to
    578   // prevent the thread from using the thread-local buffer because the thread
    579   // may not handle the flush request in time causing lost of unflushed events.
    580   void SetCurrentThreadBlocksMessageLoop();
    581 
    582  private:
    583   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
    584                            TraceBufferRingBufferGetReturnChunk);
    585   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
    586                            TraceBufferRingBufferHalfIteration);
    587   FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture,
    588                            TraceBufferRingBufferFullIteration);
    589 
    590   // This allows constructor and destructor to be private and usable only
    591   // by the Singleton class.
    592   friend struct DefaultSingletonTraits<TraceLog>;
    593 
    594   // Enable/disable each category group based on the current enabled_,
    595   // category_filter_, event_callback_ and event_callback_category_filter_.
    596   // Enable the category group if enabled_ is true and category_filter_ matches
    597   // the category group, or event_callback_ is not null and
    598   // event_callback_category_filter_ matches the category group.
    599   void UpdateCategoryGroupEnabledFlags();
    600   void UpdateCategoryGroupEnabledFlag(int category_index);
    601 
    602   class ThreadLocalEventBuffer;
    603   class OptionalAutoLock;
    604 
    605   TraceLog();
    606   ~TraceLog();
    607   const unsigned char* GetCategoryGroupEnabledInternal(const char* name);
    608   void AddMetadataEventsWhileLocked();
    609 
    610   TraceBuffer* trace_buffer() const { return logged_events_.get(); }
    611   TraceBuffer* CreateTraceBuffer();
    612 
    613   std::string EventToConsoleMessage(unsigned char phase,
    614                                     const TimeTicks& timestamp,
    615                                     TraceEvent* trace_event);
    616 
    617   TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle,
    618                                                      bool check_buffer_is_full);
    619   void CheckIfBufferIsFullWhileLocked();
    620   void SetDisabledWhileLocked();
    621 
    622   TraceEvent* GetEventByHandleInternal(TraceEventHandle handle,
    623                                        OptionalAutoLock* lock);
    624 
    625   // |generation| is used in the following callbacks to check if the callback
    626   // is called for the flush of the current |logged_events_|.
    627   void FlushCurrentThread(int generation);
    628   void ConvertTraceEventsToTraceFormat(scoped_ptr<TraceBuffer> logged_events,
    629       const TraceLog::OutputCallback& flush_output_callback);
    630   void FinishFlush(int generation);
    631   void OnFlushTimeout(int generation);
    632 
    633   int generation() const {
    634     return static_cast<int>(subtle::NoBarrier_Load(&generation_));
    635   }
    636   bool CheckGeneration(int generation) const {
    637     return generation == this->generation();
    638   }
    639   void UseNextTraceBuffer();
    640 
    641   TimeTicks OffsetNow() const {
    642     return OffsetTimestamp(TimeTicks::NowFromSystemTraceTime());
    643   }
    644   TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const {
    645     return timestamp - time_offset_;
    646   }
    647 
    648   // This lock protects TraceLog member accesses (except for members protected
    649   // by thread_info_lock_) from arbitrary threads.
    650   mutable Lock lock_;
    651   // This lock protects accesses to thread_names_, thread_event_start_times_
    652   // and thread_colors_.
    653   Lock thread_info_lock_;
    654   int locked_line_;
    655   bool enabled_;
    656   int num_traces_recorded_;
    657   scoped_ptr<TraceBuffer> logged_events_;
    658   subtle::AtomicWord /* EventCallback */ event_callback_;
    659   bool dispatching_to_observer_list_;
    660   std::vector<EnabledStateObserver*> enabled_state_observer_list_;
    661 
    662   std::string process_name_;
    663   base::hash_map<int, std::string> process_labels_;
    664   int process_sort_index_;
    665   base::hash_map<int, int> thread_sort_indices_;
    666   base::hash_map<int, std::string> thread_names_;
    667 
    668   // The following two maps are used only when ECHO_TO_CONSOLE.
    669   base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_;
    670   base::hash_map<std::string, int> thread_colors_;
    671 
    672   // XORed with TraceID to make it unlikely to collide with other processes.
    673   unsigned long long process_id_hash_;
    674 
    675   int process_id_;
    676 
    677   TimeDelta time_offset_;
    678 
    679   // Allow tests to wake up when certain events occur.
    680   WatchEventCallback watch_event_callback_;
    681   subtle::AtomicWord /* const unsigned char* */ watch_category_;
    682   std::string watch_event_name_;
    683 
    684   subtle::AtomicWord /* Options */ trace_options_;
    685 
    686   // Sampling thread handles.
    687   scoped_ptr<TraceSamplingThread> sampling_thread_;
    688   PlatformThreadHandle sampling_thread_handle_;
    689 
    690   CategoryFilter category_filter_;
    691   CategoryFilter event_callback_category_filter_;
    692 
    693   ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_;
    694   ThreadLocalBoolean thread_blocks_message_loop_;
    695   ThreadLocalBoolean thread_is_in_trace_event_;
    696 
    697   // Contains the message loops of threads that have had at least one event
    698   // added into the local event buffer. Not using MessageLoopProxy because we
    699   // need to know the life time of the message loops.
    700   hash_set<MessageLoop*> thread_message_loops_;
    701 
    702   // For events which can't be added into the thread local buffer, e.g. events
    703   // from threads without a message loop.
    704   scoped_ptr<TraceBufferChunk> thread_shared_chunk_;
    705   size_t thread_shared_chunk_index_;
    706 
    707   // Set when asynchronous Flush is in progress.
    708   OutputCallback flush_output_callback_;
    709   scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_;
    710   subtle::AtomicWord generation_;
    711 
    712   DISALLOW_COPY_AND_ASSIGN(TraceLog);
    713 };
    714 
    715 }  // namespace debug
    716 }  // namespace base
    717 
    718 #endif  // BASE_DEBUG_TRACE_EVENT_IMPL_H_
    719