| 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 |