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
44template <typename Type>
45struct DefaultSingletonTraits;
46
47#if defined(COMPILER_GCC)
48namespace BASE_HASH_NAMESPACE {
49template <>
50struct 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
58namespace base {
59
60class WaitableEvent;
61class MessageLoop;
62
63namespace debug {
64
65// For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided
66// class must implement this interface.
67class 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
82struct TraceEventHandle {
83  uint32 chunk_seq;
84  uint16 chunk_index;
85  uint16 event_index;
86};
87
88const int kTraceMaxNumArgs = 2;
89
90class 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.
187class 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.
222class 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.
243class 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
284class 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
353class TraceSamplingThread;
354
355class 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