OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include "base/trace_event/trace_log.h" | 5 #include "base/trace_event/trace_log.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "base/threading/worker_pool.h" | 33 #include "base/threading/worker_pool.h" |
34 #include "base/time/time.h" | 34 #include "base/time/time.h" |
35 #include "base/trace_event/heap_profiler.h" | 35 #include "base/trace_event/heap_profiler.h" |
36 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" | 36 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" |
37 #include "base/trace_event/memory_dump_manager.h" | 37 #include "base/trace_event/memory_dump_manager.h" |
38 #include "base/trace_event/memory_dump_provider.h" | 38 #include "base/trace_event/memory_dump_provider.h" |
39 #include "base/trace_event/process_memory_dump.h" | 39 #include "base/trace_event/process_memory_dump.h" |
40 #include "base/trace_event/trace_buffer.h" | 40 #include "base/trace_event/trace_buffer.h" |
41 #include "base/trace_event/trace_event.h" | 41 #include "base/trace_event/trace_event.h" |
42 #include "base/trace_event/trace_event_synthetic_delay.h" | 42 #include "base/trace_event/trace_event_synthetic_delay.h" |
43 #include "base/trace_event/trace_sampling_thread.h" | |
44 #include "build/build_config.h" | 43 #include "build/build_config.h" |
45 | 44 |
46 #if defined(OS_WIN) | 45 #if defined(OS_WIN) |
47 #include "base/trace_event/trace_event_etw_export_win.h" | 46 #include "base/trace_event/trace_event_etw_export_win.h" |
48 #endif | 47 #endif |
49 | 48 |
50 // The thread buckets for the sampling profiler. | |
51 BASE_EXPORT TRACE_EVENT_API_ATOMIC_WORD g_trace_state[3]; | |
52 | |
53 namespace base { | 49 namespace base { |
54 namespace internal { | 50 namespace internal { |
55 | 51 |
56 class DeleteTraceLogForTesting { | 52 class DeleteTraceLogForTesting { |
57 public: | 53 public: |
58 static void Delete() { | 54 static void Delete() { |
59 Singleton<trace_event::TraceLog, | 55 Singleton<trace_event::TraceLog, |
60 LeakySingletonTraits<trace_event::TraceLog>>::OnExit(0); | 56 LeakySingletonTraits<trace_event::TraceLog>>::OnExit(0); |
61 } | 57 } |
62 }; | 58 }; |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 TraceLog::TraceLog() | 464 TraceLog::TraceLog() |
469 : mode_(DISABLED), | 465 : mode_(DISABLED), |
470 num_traces_recorded_(0), | 466 num_traces_recorded_(0), |
471 event_callback_(0), | 467 event_callback_(0), |
472 dispatching_to_observer_list_(false), | 468 dispatching_to_observer_list_(false), |
473 process_sort_index_(0), | 469 process_sort_index_(0), |
474 process_id_hash_(0), | 470 process_id_hash_(0), |
475 process_id_(0), | 471 process_id_(0), |
476 watch_category_(0), | 472 watch_category_(0), |
477 trace_options_(kInternalRecordUntilFull), | 473 trace_options_(kInternalRecordUntilFull), |
478 sampling_thread_handle_(0), | |
479 trace_config_(TraceConfig()), | 474 trace_config_(TraceConfig()), |
480 event_callback_trace_config_(TraceConfig()), | 475 event_callback_trace_config_(TraceConfig()), |
481 thread_shared_chunk_index_(0), | 476 thread_shared_chunk_index_(0), |
482 generation_(0), | 477 generation_(0), |
483 use_worker_thread_(false) { | 478 use_worker_thread_(false) { |
484 // Trace is enabled or disabled on one thread while other threads are | 479 // Trace is enabled or disabled on one thread while other threads are |
485 // accessing the enabled flag. We don't care whether edge-case events are | 480 // accessing the enabled flag. We don't care whether edge-case events are |
486 // traced or not, so we allow races on the enabled flag to keep the trace | 481 // traced or not, so we allow races on the enabled flag to keep the trace |
487 // macros fast. | 482 // macros fast. |
488 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: | 483 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 | 777 |
783 // Clear all filters from previous tracing session. These filters are not | 778 // Clear all filters from previous tracing session. These filters are not |
784 // cleared at the end of tracing because some threads which hit trace event | 779 // cleared at the end of tracing because some threads which hit trace event |
785 // when disabling, could try to use the filters. | 780 // when disabling, could try to use the filters. |
786 g_category_group_filters.Get().clear(); | 781 g_category_group_filters.Get().clear(); |
787 | 782 |
788 trace_config_ = TraceConfig(trace_config); | 783 trace_config_ = TraceConfig(trace_config); |
789 UpdateCategoryGroupEnabledFlags(); | 784 UpdateCategoryGroupEnabledFlags(); |
790 UpdateSyntheticDelaysFromTraceConfig(); | 785 UpdateSyntheticDelaysFromTraceConfig(); |
791 | 786 |
792 if (new_options & kInternalEnableSampling) { | |
793 sampling_thread_.reset(new TraceSamplingThread); | |
794 sampling_thread_->RegisterSampleBucket( | |
795 &g_trace_state[0], "bucket0", | |
796 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | |
797 sampling_thread_->RegisterSampleBucket( | |
798 &g_trace_state[1], "bucket1", | |
799 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | |
800 sampling_thread_->RegisterSampleBucket( | |
801 &g_trace_state[2], "bucket2", | |
802 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | |
803 if (!PlatformThread::Create(0, sampling_thread_.get(), | |
804 &sampling_thread_handle_)) { | |
805 NOTREACHED() << "failed to create thread"; | |
806 } | |
807 } | |
808 | |
809 dispatching_to_observer_list_ = true; | 787 dispatching_to_observer_list_ = true; |
810 observer_list = enabled_state_observer_list_; | 788 observer_list = enabled_state_observer_list_; |
811 observer_map = async_observers_; | 789 observer_map = async_observers_; |
812 } | 790 } |
813 // Notify observers outside the lock in case they trigger trace events. | 791 // Notify observers outside the lock in case they trigger trace events. |
814 for (EnabledStateObserver* observer : observer_list) | 792 for (EnabledStateObserver* observer : observer_list) |
815 observer->OnTraceLogEnabled(); | 793 observer->OnTraceLogEnabled(); |
816 for (const auto& it : observer_map) { | 794 for (const auto& it : observer_map) { |
817 it.second.task_runner->PostTask( | 795 it.second.task_runner->PostTask( |
818 FROM_HERE, Bind(&AsyncEnabledStateObserver::OnTraceLogEnabled, | 796 FROM_HERE, Bind(&AsyncEnabledStateObserver::OnTraceLogEnabled, |
819 it.second.observer)); | 797 it.second.observer)); |
820 } | 798 } |
821 | 799 |
822 { | 800 { |
823 AutoLock lock(lock_); | 801 AutoLock lock(lock_); |
824 dispatching_to_observer_list_ = false; | 802 dispatching_to_observer_list_ = false; |
825 } | 803 } |
826 } | 804 } |
827 | 805 |
828 void TraceLog::SetArgumentFilterPredicate( | 806 void TraceLog::SetArgumentFilterPredicate( |
829 const ArgumentFilterPredicate& argument_filter_predicate) { | 807 const ArgumentFilterPredicate& argument_filter_predicate) { |
830 AutoLock lock(lock_); | 808 AutoLock lock(lock_); |
831 DCHECK(!argument_filter_predicate.is_null()); | 809 DCHECK(!argument_filter_predicate.is_null()); |
832 DCHECK(argument_filter_predicate_.is_null()); | 810 DCHECK(argument_filter_predicate_.is_null()); |
833 argument_filter_predicate_ = argument_filter_predicate; | 811 argument_filter_predicate_ = argument_filter_predicate; |
834 } | 812 } |
835 | 813 |
836 TraceLog::InternalTraceOptions TraceLog::GetInternalOptionsFromTraceConfig( | 814 TraceLog::InternalTraceOptions TraceLog::GetInternalOptionsFromTraceConfig( |
837 const TraceConfig& config) { | 815 const TraceConfig& config) { |
838 InternalTraceOptions ret = | 816 InternalTraceOptions ret = config.IsArgumentFilterEnabled() |
839 config.IsSamplingEnabled() ? kInternalEnableSampling : kInternalNone; | 817 ? kInternalEnableArgumentFilter |
840 if (config.IsArgumentFilterEnabled()) | 818 : kInternalNone; |
841 ret |= kInternalEnableArgumentFilter; | |
842 switch (config.GetTraceRecordMode()) { | 819 switch (config.GetTraceRecordMode()) { |
843 case RECORD_UNTIL_FULL: | 820 case RECORD_UNTIL_FULL: |
844 return ret | kInternalRecordUntilFull; | 821 return ret | kInternalRecordUntilFull; |
845 case RECORD_CONTINUOUSLY: | 822 case RECORD_CONTINUOUSLY: |
846 return ret | kInternalRecordContinuously; | 823 return ret | kInternalRecordContinuously; |
847 case ECHO_TO_CONSOLE: | 824 case ECHO_TO_CONSOLE: |
848 return ret | kInternalEchoToConsole; | 825 return ret | kInternalEchoToConsole; |
849 case RECORD_AS_MUCH_AS_POSSIBLE: | 826 case RECORD_AS_MUCH_AS_POSSIBLE: |
850 return ret | kInternalRecordAsMuchAsPossible; | 827 return ret | kInternalRecordAsMuchAsPossible; |
851 } | 828 } |
(...skipping 18 matching lines...) Expand all Loading... |
870 return; | 847 return; |
871 | 848 |
872 if (dispatching_to_observer_list_) { | 849 if (dispatching_to_observer_list_) { |
873 DLOG(ERROR) | 850 DLOG(ERROR) |
874 << "Cannot manipulate TraceLog::Enabled state from an observer."; | 851 << "Cannot manipulate TraceLog::Enabled state from an observer."; |
875 return; | 852 return; |
876 } | 853 } |
877 | 854 |
878 mode_ = DISABLED; | 855 mode_ = DISABLED; |
879 | 856 |
880 if (sampling_thread_) { | |
881 // Stop the sampling thread. | |
882 sampling_thread_->Stop(); | |
883 lock_.Release(); | |
884 PlatformThread::Join(sampling_thread_handle_); | |
885 lock_.Acquire(); | |
886 sampling_thread_handle_ = PlatformThreadHandle(); | |
887 sampling_thread_.reset(); | |
888 } | |
889 | |
890 trace_config_.Clear(); | 857 trace_config_.Clear(); |
891 subtle::NoBarrier_Store(&watch_category_, 0); | 858 subtle::NoBarrier_Store(&watch_category_, 0); |
892 watch_event_name_.clear(); | 859 watch_event_name_.clear(); |
893 UpdateCategoryGroupEnabledFlags(); | 860 UpdateCategoryGroupEnabledFlags(); |
894 AddMetadataEventsWhileLocked(); | 861 AddMetadataEventsWhileLocked(); |
895 | 862 |
896 // Remove metadata events so they will not get added to a subsequent trace. | 863 // Remove metadata events so they will not get added to a subsequent trace. |
897 metadata_events_.clear(); | 864 metadata_events_.clear(); |
898 | 865 |
899 dispatching_to_observer_list_ = true; | 866 dispatching_to_observer_list_ = true; |
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1758 | 1725 |
1759 // If buffer is full, add a metadata record to report this. | 1726 // If buffer is full, add a metadata record to report this. |
1760 if (!buffer_limit_reached_timestamp_.is_null()) { | 1727 if (!buffer_limit_reached_timestamp_.is_null()) { |
1761 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), | 1728 InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), |
1762 current_thread_id, "trace_buffer_overflowed", | 1729 current_thread_id, "trace_buffer_overflowed", |
1763 "overflowed_at_ts", | 1730 "overflowed_at_ts", |
1764 buffer_limit_reached_timestamp_); | 1731 buffer_limit_reached_timestamp_); |
1765 } | 1732 } |
1766 } | 1733 } |
1767 | 1734 |
1768 void TraceLog::WaitSamplingEventForTesting() { | |
1769 if (!sampling_thread_) | |
1770 return; | |
1771 sampling_thread_->WaitSamplingEventForTesting(); | |
1772 } | |
1773 | |
1774 void TraceLog::DeleteForTesting() { | 1735 void TraceLog::DeleteForTesting() { |
1775 internal::DeleteTraceLogForTesting::Delete(); | 1736 internal::DeleteTraceLogForTesting::Delete(); |
1776 } | 1737 } |
1777 | 1738 |
1778 void TraceLog::SetTraceEventFilterConstructorForTesting( | 1739 void TraceLog::SetTraceEventFilterConstructorForTesting( |
1779 TraceEventFilterConstructorForTesting predicate) { | 1740 TraceEventFilterConstructorForTesting predicate) { |
1780 g_trace_event_filter_constructor_for_testing = predicate; | 1741 g_trace_event_filter_constructor_for_testing = predicate; |
1781 } | 1742 } |
1782 | 1743 |
1783 TraceEvent* TraceLog::GetEventByHandle(TraceEventHandle handle) { | 1744 TraceEvent* TraceLog::GetEventByHandle(TraceEventHandle handle) { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1964 } | 1925 } |
1965 | 1926 |
1966 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 1927 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
1967 if (*category_group_enabled_) { | 1928 if (*category_group_enabled_) { |
1968 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, | 1929 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, |
1969 event_handle_); | 1930 event_handle_); |
1970 } | 1931 } |
1971 } | 1932 } |
1972 | 1933 |
1973 } // namespace trace_event_internal | 1934 } // namespace trace_event_internal |
OLD | NEW |