| Index: base/trace_event/trace_log.cc
|
| diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc
|
| index 866111a4d29620abac1835c6ddbb2ec43ce11070..eca21dfa5613b498bb39007b5d5238767a8bd366 100644
|
| --- a/base/trace_event/trace_log.cc
|
| +++ b/base/trace_event/trace_log.cc
|
| @@ -465,7 +465,7 @@ TraceLog* TraceLog::GetInstance() {
|
| }
|
|
|
| TraceLog::TraceLog()
|
| - : mode_(DISABLED),
|
| + : mode_(0),
|
| num_traces_recorded_(0),
|
| event_callback_(0),
|
| dispatching_to_observer_list_(false),
|
| @@ -564,7 +564,7 @@ const char* TraceLog::GetCategoryGroupName(
|
| void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) {
|
| unsigned char enabled_flag = 0;
|
| const char* category_group = g_category_groups[category_index];
|
| - if (mode_ == RECORDING_MODE &&
|
| + if (mode_ & RECORDING_MODE &&
|
| trace_config_.IsCategoryGroupEnabled(category_group)) {
|
| enabled_flag |= ENABLED_FOR_RECORDING;
|
| }
|
| @@ -584,12 +584,12 @@ void TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) {
|
| // TODO(primiano): this is a temporary workaround for catapult:#2341,
|
| // to guarantee that metadata events are always added even if the category
|
| // filter is "-*". See crbug.com/618054 for more details and long-term fix.
|
| - if (mode_ == RECORDING_MODE && !strcmp(category_group, "__metadata"))
|
| + if (mode_ & RECORDING_MODE && !strcmp(category_group, "__metadata"))
|
| enabled_flag |= ENABLED_FOR_RECORDING;
|
|
|
| uint32_t enabled_filters_bitmap = 0;
|
| int index = 0;
|
| - for (const auto& event_filter : trace_config_.event_filters()) {
|
| + for (const auto& event_filter : event_filters_enabled_) {
|
| if (event_filter.IsCategoryGroupEnabled(category_group)) {
|
| enabled_flag |= ENABLED_FOR_FILTERING;
|
| DCHECK(g_category_group_filters.Get()[index]);
|
| @@ -618,7 +618,7 @@ void TraceLog::CreateFiltersForTraceConfig() {
|
| if (g_category_group_filters.Get().size())
|
| return;
|
|
|
| - for (auto& event_filter : trace_config_.event_filters()) {
|
| + for (auto& event_filter : event_filters_enabled_) {
|
| if (g_category_group_filters.Get().size() >= MAX_TRACE_EVENT_FILTERS) {
|
| NOTREACHED()
|
| << "Too many trace event filters installed in the current session";
|
| @@ -731,7 +731,7 @@ void TraceLog::GetKnownCategoryGroups(
|
| category_groups->push_back(g_category_groups[i]);
|
| }
|
|
|
| -void TraceLog::SetEnabled(const TraceConfig& trace_config, Mode mode) {
|
| +void TraceLog::SetEnabled(const TraceConfig& trace_config, Mode new_mode) {
|
| std::vector<EnabledStateObserver*> observer_list;
|
| std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> observer_map;
|
| {
|
| @@ -745,32 +745,54 @@ void TraceLog::SetEnabled(const TraceConfig& trace_config, Mode mode) {
|
|
|
| InternalTraceOptions old_options = trace_options();
|
|
|
| - if (IsEnabled()) {
|
| - if (new_options != old_options) {
|
| - DLOG(ERROR) << "Attempting to re-enable tracing with a different "
|
| - << "set of options.";
|
| - }
|
| -
|
| - if (mode != mode_) {
|
| - DLOG(ERROR) << "Attempting to re-enable tracing with a different mode.";
|
| - }
|
| -
|
| - DCHECK(!trace_config.event_filters().size())
|
| - << "Adding new filters while tracing was already enabled is not "
|
| - "supported.";
|
| -
|
| - trace_config_.Merge(trace_config);
|
| - UpdateCategoryGroupEnabledFlags();
|
| + if (dispatching_to_observer_list_) {
|
| + NOTREACHED()
|
| + << "Cannot manipulate TraceLog::Enabled state from an observer.";
|
| return;
|
| }
|
|
|
| - if (dispatching_to_observer_list_) {
|
| - DLOG(ERROR)
|
| - << "Cannot manipulate TraceLog::Enabled state from an observer.";
|
| + // Update event filters:
|
| + DCHECK(
|
| + !(new_mode == FILTERING_MODE && trace_config.event_filters().empty()))
|
| + << "Attempting to enable filtering without any filters";
|
| + if (!mode_) {
|
| + // Clear all filters from previous tracing session. These filters are not
|
| + // cleared at the end of tracing because some threads which hit trace
|
| + // event when disabling, could try to use the filters.
|
| + g_category_group_filters.Get().clear();
|
| + }
|
| + if (event_filters_enabled_.empty()) {
|
| + // Use the given event filters only if filtering was not enabled.
|
| + event_filters_enabled_ = trace_config.event_filters();
|
| + } else if (new_mode == FILTERING_MODE) {
|
| + NOTREACHED() << "Attempting to re-enable filtering when filters are "
|
| + "already enabled.";
|
| return;
|
| }
|
|
|
| - mode_ = mode;
|
| + // Update trace config for recording.
|
| + bool already_recording = mode_ & RECORDING_MODE;
|
| + if (new_mode == RECORDING_MODE) {
|
| + if (already_recording) {
|
| + DCHECK_EQ(new_options, old_options) << "Attempting to re-enable "
|
| + "tracing with a different set "
|
| + "of options.";
|
| + trace_config_.Merge(trace_config);
|
| + } else {
|
| + trace_config_ = trace_config;
|
| + }
|
| + }
|
| + // Keep the |trace_config_| updated with only enabled filters in case anyone
|
| + // tries to read it using |GetCurrentTraceConfig|
|
| + trace_config_.SetEventFilterConfigs(event_filters_enabled_);
|
| +
|
| + mode_ |= new_mode;
|
| + UpdateCategoryGroupEnabledFlags();
|
| +
|
| + // Do not notify observers and create trace buffer if enabled for filtering
|
| + // or if recording was already enabled.
|
| + if (new_mode == FILTERING_MODE || already_recording)
|
| + return;
|
|
|
| if (new_options != old_options) {
|
| subtle::NoBarrier_Store(&trace_options_, new_options);
|
| @@ -779,12 +801,6 @@ void TraceLog::SetEnabled(const TraceConfig& trace_config, Mode mode) {
|
|
|
| num_traces_recorded_++;
|
|
|
| - // Clear all filters from previous tracing session. These filters are not
|
| - // cleared at the end of tracing because some threads which hit trace event
|
| - // when disabling, could try to use the filters.
|
| - g_category_group_filters.Get().clear();
|
| -
|
| - trace_config_ = TraceConfig(trace_config);
|
| UpdateCategoryGroupEnabledFlags();
|
| UpdateSyntheticDelaysFromTraceConfig();
|
|
|
| @@ -859,23 +875,26 @@ TraceConfig TraceLog::GetCurrentTraceConfig() const {
|
|
|
| void TraceLog::SetDisabled() {
|
| AutoLock lock(lock_);
|
| - SetDisabledWhileLocked();
|
| + SetDisabledWhileLocked(RECORDING_MODE);
|
| +}
|
| +
|
| +void TraceLog::SetDisabled(Mode mode) {
|
| + AutoLock lock(lock_);
|
| + SetDisabledWhileLocked(mode);
|
| }
|
|
|
| -void TraceLog::SetDisabledWhileLocked() {
|
| +void TraceLog::SetDisabledWhileLocked(Mode mode) {
|
| lock_.AssertAcquired();
|
|
|
| - if (!IsEnabled())
|
| + if (!(mode_ & mode))
|
| return;
|
|
|
| if (dispatching_to_observer_list_) {
|
| - DLOG(ERROR)
|
| + NOTREACHED()
|
| << "Cannot manipulate TraceLog::Enabled state from an observer.";
|
| return;
|
| }
|
|
|
| - mode_ = DISABLED;
|
| -
|
| if (sampling_thread_) {
|
| // Stop the sampling thread.
|
| sampling_thread_->Stop();
|
| @@ -886,10 +905,21 @@ void TraceLog::SetDisabledWhileLocked() {
|
| sampling_thread_.reset();
|
| }
|
|
|
| - trace_config_.Clear();
|
| + mode_ &= ~mode;
|
| + if (mode == RECORDING_MODE)
|
| + trace_config_.Clear();
|
| + // Clear the filters if tracing is no longer enabled or filtering is disabled.
|
| + if (!mode || mode == FILTERING_MODE)
|
| + event_filters_enabled_.clear();
|
| +
|
| subtle::NoBarrier_Store(&watch_category_, 0);
|
| watch_event_name_.clear();
|
| UpdateCategoryGroupEnabledFlags();
|
| +
|
| + // Skip adding metadata events and notifying observers for filtering mode.
|
| + if (mode == FILTERING_MODE)
|
| + return;
|
| +
|
| AddMetadataEventsWhileLocked();
|
|
|
| // Remove metadata events so they will not get added to a subsequent trace.
|
| @@ -916,6 +946,11 @@ void TraceLog::SetDisabledWhileLocked() {
|
| dispatching_to_observer_list_ = false;
|
| }
|
|
|
| +bool TraceLog::IsFilteringEnabled() {
|
| + AutoLock lock(lock_);
|
| + return !event_filters_enabled_.empty();
|
| +}
|
| +
|
| int TraceLog::GetNumTracesRecorded() {
|
| AutoLock lock(lock_);
|
| if (!IsEnabled())
|
| @@ -989,7 +1024,7 @@ void TraceLog::CheckIfBufferIsFullWhileLocked() {
|
| if (buffer_limit_reached_timestamp_.is_null()) {
|
| buffer_limit_reached_timestamp_ = OffsetNow();
|
| }
|
| - SetDisabledWhileLocked();
|
| + SetDisabledWhileLocked(RECORDING_MODE);
|
| }
|
| }
|
|
|
| @@ -1376,11 +1411,6 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
|
| TimeTicks offset_event_timestamp = OffsetTimestamp(timestamp);
|
| ThreadTicks thread_now = ThreadNow();
|
|
|
| - // |thread_local_event_buffer_| can be null if the current thread doesn't have
|
| - // a message loop or the message loop is blocked.
|
| - InitializeThreadLocalEventBufferIfSupported();
|
| - auto* thread_local_event_buffer = thread_local_event_buffer_.Get();
|
| -
|
| // Check and update the current thread name only if the event is for the
|
| // current thread to avoid locks in most cases.
|
| if (thread_id == static_cast<int>(PlatformThread::CurrentId())) {
|
| @@ -1452,6 +1482,11 @@ TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
|
| // filters indicates or category is not enabled for filtering.
|
| if ((*category_group_enabled & ENABLED_FOR_RECORDING) &&
|
| !disabled_by_filters) {
|
| + // |thread_local_event_buffer_| can be null if the current thread doesn't
|
| + // have a message loop or the message loop is blocked.
|
| + InitializeThreadLocalEventBufferIfSupported();
|
| + auto* thread_local_event_buffer = thread_local_event_buffer_.Get();
|
| +
|
| OptionalAutoLock lock(&lock_);
|
|
|
| TraceEvent* trace_event = NULL;
|
|
|