| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 | 5 |
| 6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
| 7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
| 8 | 8 |
| 9 #include <stack> | 9 #include <stack> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/atomicops.h" |
| 13 #include "base/callback.h" | 14 #include "base/callback.h" |
| 14 #include "base/containers/hash_tables.h" | 15 #include "base/containers/hash_tables.h" |
| 15 #include "base/gtest_prod_util.h" | 16 #include "base/gtest_prod_util.h" |
| 16 #include "base/memory/ref_counted_memory.h" | 17 #include "base/memory/ref_counted_memory.h" |
| 17 #include "base/memory/scoped_vector.h" | 18 #include "base/memory/scoped_vector.h" |
| 18 #include "base/observer_list.h" | 19 #include "base/observer_list.h" |
| 19 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
| 20 #include "base/synchronization/condition_variable.h" | 21 #include "base/synchronization/condition_variable.h" |
| 21 #include "base/synchronization/lock.h" | 22 #include "base/synchronization/lock.h" |
| 22 #include "base/threading/thread.h" | 23 #include "base/threading/thread.h" |
| 24 #include "base/threading/thread_local.h" |
| 23 #include "base/timer/timer.h" | 25 #include "base/timer/timer.h" |
| 24 | 26 |
| 25 // Older style trace macros with explicit id and extra data | 27 // Older style trace macros with explicit id and extra data |
| 26 // Only these macros result in publishing data to ETW as currently implemented. | 28 // Only these macros result in publishing data to ETW as currently implemented. |
| 27 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ | 29 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ |
| 28 base::debug::TraceLog::AddTraceEventEtw( \ | 30 base::debug::TraceLog::AddTraceEventEtw( \ |
| 29 TRACE_EVENT_PHASE_BEGIN, \ | 31 TRACE_EVENT_PHASE_BEGIN, \ |
| 30 name, reinterpret_cast<const void*>(id), extra) | 32 name, reinterpret_cast<const void*>(id), extra) |
| 31 | 33 |
| 32 #define TRACE_EVENT_END_ETW(name, id, extra) \ | 34 #define TRACE_EVENT_END_ETW(name, id, extra) \ |
| 33 base::debug::TraceLog::AddTraceEventEtw( \ | 35 base::debug::TraceLog::AddTraceEventEtw( \ |
| 34 TRACE_EVENT_PHASE_END, \ | 36 TRACE_EVENT_PHASE_END, \ |
| 35 name, reinterpret_cast<const void*>(id), extra) | 37 name, reinterpret_cast<const void*>(id), extra) |
| 36 | 38 |
| 37 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ | 39 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ |
| 38 base::debug::TraceLog::AddTraceEventEtw( \ | 40 base::debug::TraceLog::AddTraceEventEtw( \ |
| 39 TRACE_EVENT_PHASE_INSTANT, \ | 41 TRACE_EVENT_PHASE_INSTANT, \ |
| 40 name, reinterpret_cast<const void*>(id), extra) | 42 name, reinterpret_cast<const void*>(id), extra) |
| 41 | 43 |
| 42 template <typename Type> | 44 template <typename Type> |
| 43 struct DefaultSingletonTraits; | 45 struct DefaultSingletonTraits; |
| 44 | 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 |
| 45 namespace base { | 58 namespace base { |
| 46 | 59 |
| 47 class WaitableEvent; | 60 class WaitableEvent; |
| 61 class MessageLoop; |
| 48 | 62 |
| 49 namespace debug { | 63 namespace debug { |
| 50 | 64 |
| 51 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided | 65 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided |
| 52 // class must implement this interface. | 66 // class must implement this interface. |
| 53 class ConvertableToTraceFormat { | 67 class ConvertableToTraceFormat { |
| 54 public: | 68 public: |
| 55 virtual ~ConvertableToTraceFormat() {} | 69 virtual ~ConvertableToTraceFormat() {} |
| 56 | 70 |
| 57 // Append the class info to the provided |out| string. The appended | 71 // Append the class info to the provided |out| string. The appended |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 std::string* out); | 117 std::string* out); |
| 104 void AppendAsJSON(std::string* out) const; | 118 void AppendAsJSON(std::string* out) const; |
| 105 void AppendPrettyPrinted(std::ostringstream* out) const; | 119 void AppendPrettyPrinted(std::ostringstream* out) const; |
| 106 | 120 |
| 107 static void AppendValueAsJSON(unsigned char type, | 121 static void AppendValueAsJSON(unsigned char type, |
| 108 TraceValue value, | 122 TraceValue value, |
| 109 std::string* out); | 123 std::string* out); |
| 110 | 124 |
| 111 TimeTicks timestamp() const { return timestamp_; } | 125 TimeTicks timestamp() const { return timestamp_; } |
| 112 TimeTicks thread_timestamp() const { return thread_timestamp_; } | 126 TimeTicks thread_timestamp() const { return thread_timestamp_; } |
| 127 char phase() const { return phase_; } |
| 128 int thread_id() const { return thread_id_; } |
| 113 | 129 |
| 114 // Exposed for unittesting: | 130 // Exposed for unittesting: |
| 115 | 131 |
| 116 const base::RefCountedString* parameter_copy_storage() const { | 132 const base::RefCountedString* parameter_copy_storage() const { |
| 117 return parameter_copy_storage_.get(); | 133 return parameter_copy_storage_.get(); |
| 118 } | 134 } |
| 119 | 135 |
| 120 const unsigned char* category_group_enabled() const { | 136 const unsigned char* category_group_enabled() const { |
| 121 return category_group_enabled_; | 137 return category_group_enabled_; |
| 122 } | 138 } |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 RECORD_UNTIL_FULL = 1 << 0, | 305 RECORD_UNTIL_FULL = 1 << 0, |
| 290 | 306 |
| 291 // Record until the user ends the trace. The trace buffer is a fixed size | 307 // Record until the user ends the trace. The trace buffer is a fixed size |
| 292 // and we use it as a ring buffer during recording. | 308 // and we use it as a ring buffer during recording. |
| 293 RECORD_CONTINUOUSLY = 1 << 1, | 309 RECORD_CONTINUOUSLY = 1 << 1, |
| 294 | 310 |
| 295 // Enable the sampling profiler. | 311 // Enable the sampling profiler. |
| 296 ENABLE_SAMPLING = 1 << 2, | 312 ENABLE_SAMPLING = 1 << 2, |
| 297 | 313 |
| 298 // Echo to console. Events are discarded. | 314 // Echo to console. Events are discarded. |
| 299 ECHO_TO_CONSOLE = 1 << 3 | 315 ECHO_TO_CONSOLE = 1 << 3, |
| 300 }; | 316 }; |
| 301 | 317 |
| 302 static TraceLog* GetInstance(); | 318 static TraceLog* GetInstance(); |
| 303 | 319 |
| 304 // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if | 320 // Convert the given string to trace options. Defaults to RECORD_UNTIL_FULL if |
| 305 // the string does not provide valid options. | 321 // the string does not provide valid options. |
| 306 static Options TraceOptionsFromString(const std::string& str); | 322 static Options TraceOptionsFromString(const std::string& str); |
| 307 | 323 |
| 308 // Get set of known category groups. This can change as new code paths are | 324 // Get set of known category groups. This can change as new code paths are |
| 309 // reached. The known category groups are inserted into |category_groups|. | 325 // reached. The known category groups are inserted into |category_groups|. |
| 310 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); | 326 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); |
| 311 | 327 |
| 312 // Retrieves the current CategoryFilter. | 328 // Retrieves the current CategoryFilter. |
| 313 const CategoryFilter& GetCurrentCategoryFilter(); | 329 const CategoryFilter& GetCurrentCategoryFilter(); |
| 314 | 330 |
| 315 Options trace_options() const { return trace_options_; } | 331 Options trace_options() const { |
| 332 return static_cast<Options>(subtle::NoBarrier_Load(&trace_options_)); |
| 333 } |
| 316 | 334 |
| 317 // Enables tracing. See CategoryFilter comments for details | 335 // Enables tracing. See CategoryFilter comments for details |
| 318 // on how to control what categories will be traced. | 336 // on how to control what categories will be traced. |
| 319 void SetEnabled(const CategoryFilter& category_filter, Options options); | 337 void SetEnabled(const CategoryFilter& category_filter, Options options); |
| 320 | 338 |
| 321 // Disable tracing for all categories. | 339 // Disable tracing for all categories. |
| 322 void SetDisabled(); | 340 void SetDisabled(); |
| 323 bool IsEnabled() { return !!enable_count_; } | 341 bool IsEnabled() { return !!enable_count_; } |
| 324 | 342 |
| 325 // The number of times we have begun recording traces. If tracing is off, | 343 // The number of times we have begun recording traces. If tracing is off, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 const char* name, | 389 const char* name, |
| 372 unsigned long long id, | 390 unsigned long long id, |
| 373 int num_args, | 391 int num_args, |
| 374 const char* const arg_names[], | 392 const char* const arg_names[], |
| 375 const unsigned char arg_types[], | 393 const unsigned char arg_types[], |
| 376 const unsigned long long arg_values[], | 394 const unsigned long long arg_values[], |
| 377 unsigned char flags); | 395 unsigned char flags); |
| 378 void SetEventCallback(EventCallback cb); | 396 void SetEventCallback(EventCallback cb); |
| 379 | 397 |
| 380 // Flush all collected events to the given output callback. The callback will | 398 // Flush all collected events to the given output callback. The callback will |
| 381 // be called one or more times with IPC-bite-size chunks. The string format is | 399 // be called one or more times either synchronously or asynchronously from |
| 400 // the current thread with IPC-bite-size chunks. The string format is |
| 382 // undefined. Use TraceResultBuffer to convert one or more trace strings to | 401 // undefined. Use TraceResultBuffer to convert one or more trace strings to |
| 383 // JSON. | 402 // JSON. The callback can be null if the caller doesn't want any data. |
| 384 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> | 403 // Due to the implementation of thread-local buffers, flush can't be |
| 385 OutputCallback; | 404 // done when tracing is enabled. If called when tracing is enabled, the |
| 405 // callback will be called directly with (empty_string, false) to indicate |
| 406 // the end of this unsuccessful flush. |
| 407 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&, |
| 408 bool has_more_events)> OutputCallback; |
| 386 void Flush(const OutputCallback& cb); | 409 void Flush(const OutputCallback& cb); |
| 387 | 410 |
| 388 // Called by TRACE_EVENT* macros, don't call this directly. | 411 // Called by TRACE_EVENT* macros, don't call this directly. |
| 389 // The name parameter is a category group for example: | 412 // The name parameter is a category group for example: |
| 390 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") | 413 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") |
| 391 static const unsigned char* GetCategoryGroupEnabled(const char* name); | 414 static const unsigned char* GetCategoryGroupEnabled(const char* name); |
| 392 static const char* GetCategoryGroupName( | 415 static const char* GetCategoryGroupName( |
| 393 const unsigned char* category_group_enabled); | 416 const unsigned char* category_group_enabled); |
| 394 | 417 |
| 395 // Called by TRACE_EVENT* macros, don't call this directly. | 418 // Called by TRACE_EVENT* macros, don't call this directly. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 // notifications from previous calls to AddNotificationWhileLocked, this | 545 // notifications from previous calls to AddNotificationWhileLocked, this |
| 523 // will call the NotificationCallback. | 546 // will call the NotificationCallback. |
| 524 inline void SendNotificationIfAny(); | 547 inline void SendNotificationIfAny(); |
| 525 | 548 |
| 526 private: | 549 private: |
| 527 TraceLog* trace_log_; | 550 TraceLog* trace_log_; |
| 528 NotificationCallback callback_copy_; | 551 NotificationCallback callback_copy_; |
| 529 int notification_; | 552 int notification_; |
| 530 }; | 553 }; |
| 531 | 554 |
| 555 class ThreadLocalEventBuffer; |
| 556 |
| 532 TraceLog(); | 557 TraceLog(); |
| 533 ~TraceLog(); | 558 ~TraceLog(); |
| 534 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); | 559 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); |
| 535 void AddMetadataEvents(); | 560 void AddMetadataEvents(); |
| 536 | 561 |
| 537 #if defined(OS_ANDROID) | 562 #if defined(OS_ANDROID) |
| 538 void SendToATrace(char phase, | 563 void SendToATrace(char phase, |
| 539 const char* category_group, | 564 const char* category_group, |
| 540 const char* name, | 565 const char* name, |
| 541 unsigned long long id, | 566 unsigned long long id, |
| 542 int num_args, | 567 int num_args, |
| 543 const char** arg_names, | 568 const char** arg_names, |
| 544 const unsigned char* arg_types, | 569 const unsigned char* arg_types, |
| 545 const unsigned long long* arg_values, | 570 const unsigned long long* arg_values, |
| 546 scoped_ptr<ConvertableToTraceFormat> convertable_values[], | 571 scoped_ptr<ConvertableToTraceFormat> convertable_values[], |
| 547 unsigned char flags); | 572 unsigned char flags); |
| 548 static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled); | 573 static void ApplyATraceEnabledFlag(unsigned char* category_group_enabled); |
| 549 #endif | 574 #endif |
| 550 | 575 |
| 551 TraceBuffer* GetTraceBuffer(); | 576 TraceBuffer* GetTraceBuffer(); |
| 552 | 577 |
| 553 // TODO(nduca): switch to per-thread trace buffers to reduce thread | 578 void AddEventToMainBufferWhileLocked(const TraceEvent& trace_event); |
| 554 // synchronization. | 579 void CheckIfBufferIsFullWhileLocked(NotificationHelper* notifier); |
| 580 // |flush_count| is used in the following callbacks to check if the callback |
| 581 // is called for the current flush. |
| 582 void FlushCurrentThread(int flush_count); |
| 583 void FinishFlush(int flush_count); |
| 584 void OnFlushTimeout(int flush_count); |
| 585 |
| 555 // This lock protects TraceLog member accesses from arbitrary threads. | 586 // This lock protects TraceLog member accesses from arbitrary threads. |
| 556 Lock lock_; | 587 Lock lock_; |
| 588 int locked_line_; |
| 557 int enable_count_; | 589 int enable_count_; |
| 558 int num_traces_recorded_; | 590 int num_traces_recorded_; |
| 591 subtle::AtomicWord /* bool */ buffer_is_full_; |
| 559 NotificationCallback notification_callback_; | 592 NotificationCallback notification_callback_; |
| 560 scoped_ptr<TraceBuffer> logged_events_; | 593 scoped_ptr<TraceBuffer> logged_events_; |
| 561 EventCallback event_callback_; | 594 subtle::AtomicWord /* EventCallback */ event_callback_; |
| 562 bool dispatching_to_observer_list_; | 595 bool dispatching_to_observer_list_; |
| 563 std::vector<EnabledStateObserver*> enabled_state_observer_list_; | 596 std::vector<EnabledStateObserver*> enabled_state_observer_list_; |
| 564 | 597 |
| 565 std::string process_name_; | 598 std::string process_name_; |
| 566 base::hash_map<int, std::string> process_labels_; | 599 base::hash_map<int, std::string> process_labels_; |
| 567 int process_sort_index_; | 600 int process_sort_index_; |
| 568 base::hash_map<int, int> thread_sort_indices_; | 601 base::hash_map<int, int> thread_sort_indices_; |
| 602 base::hash_map<int, std::string> thread_names_; |
| 569 | 603 |
| 570 base::hash_map<int, std::string> thread_names_; | 604 // The following two maps are used only when ECHO_TO_CONSOLE. |
| 571 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; | 605 base::hash_map<int, std::stack<TimeTicks> > thread_event_start_times_; |
| 572 base::hash_map<std::string, int> thread_colors_; | 606 base::hash_map<std::string, int> thread_colors_; |
| 573 | 607 |
| 574 // XORed with TraceID to make it unlikely to collide with other processes. | 608 // XORed with TraceID to make it unlikely to collide with other processes. |
| 575 unsigned long long process_id_hash_; | 609 unsigned long long process_id_hash_; |
| 576 | 610 |
| 577 int process_id_; | 611 int process_id_; |
| 578 | 612 |
| 579 TimeDelta time_offset_; | 613 TimeDelta time_offset_; |
| 580 | 614 |
| 581 // Allow tests to wake up when certain events occur. | 615 // Allow tests to wake up when certain events occur. |
| 582 const unsigned char* watch_category_; | 616 subtle::AtomicWord /* const unsigned char* */ watch_category_; |
| 583 std::string watch_event_name_; | 617 std::string watch_event_name_; |
| 584 | 618 |
| 585 Options trace_options_; | 619 subtle::AtomicWord /* Options */ trace_options_; |
| 586 | 620 |
| 587 // Sampling thread handles. | 621 // Sampling thread handles. |
| 588 scoped_ptr<TraceSamplingThread> sampling_thread_; | 622 scoped_ptr<TraceSamplingThread> sampling_thread_; |
| 589 PlatformThreadHandle sampling_thread_handle_; | 623 PlatformThreadHandle sampling_thread_handle_; |
| 590 | 624 |
| 591 CategoryFilter category_filter_; | 625 CategoryFilter category_filter_; |
| 592 | 626 |
| 627 ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_; |
| 628 |
| 629 // Contains the message loops of threads that have had at least one event |
| 630 // added into the local event buffer. Not using MessageLoopProxy because we |
| 631 // need to know the life time of the message loops. |
| 632 base::hash_set<MessageLoop*> thread_message_loops_; |
| 633 |
| 634 // Set when asynchronous Flush is in progress. |
| 635 OutputCallback flush_output_callback_; |
| 636 scoped_refptr<MessageLoopProxy> flush_message_loop_proxy_; |
| 637 int flush_count_; |
| 638 |
| 593 DISALLOW_COPY_AND_ASSIGN(TraceLog); | 639 DISALLOW_COPY_AND_ASSIGN(TraceLog); |
| 594 }; | 640 }; |
| 595 | 641 |
| 596 } // namespace debug | 642 } // namespace debug |
| 597 } // namespace base | 643 } // namespace base |
| 598 | 644 |
| 599 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ | 645 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ |
| OLD | NEW |