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