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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 } | 126 } |
127 | 127 |
128 private: | 128 private: |
129 std::unordered_set<std::string> whitelist_; | 129 std::unordered_set<std::string> whitelist_; |
130 }; | 130 }; |
131 | 131 |
132 base::LazyInstance< | 132 base::LazyInstance< |
133 std::list<std::unique_ptr<TraceLog::TraceEventFilter>>>::Leaky | 133 std::list<std::unique_ptr<TraceLog::TraceEventFilter>>>::Leaky |
134 g_category_group_filter[MAX_CATEGORY_GROUPS] = {LAZY_INSTANCE_INITIALIZER}; | 134 g_category_group_filter[MAX_CATEGORY_GROUPS] = {LAZY_INSTANCE_INITIALIZER}; |
135 | 135 |
136 class HeapProfilerFilter : public TraceLog::TraceEventFilter { | |
137 public: | |
138 HeapProfilerFilter() {} | |
139 | |
140 bool FilterTraceEvent(const TraceEvent& trace_event) const override { | |
141 // TODO(primiano): Add support for events with copied name crbug.com/581078 | |
142 if (!(trace_event.flags() & TRACE_EVENT_FLAG_COPY)) { | |
143 if (AllocationContextTracker::capture_mode() == | |
144 AllocationContextTracker::CaptureMode::PSEUDO_STACK) { | |
145 if (trace_event.phase() == TRACE_EVENT_PHASE_BEGIN || | |
146 trace_event.phase() == TRACE_EVENT_PHASE_COMPLETE) { | |
147 AllocationContextTracker::GetInstanceForCurrentThread() | |
148 ->PushPseudoStackFrame(trace_event.name()); | |
149 } else if (trace_event.phase() == TRACE_EVENT_PHASE_END) | |
150 // The pop for |TRACE_EVENT_PHASE_COMPLETE| events is in |EndEvent|. | |
151 AllocationContextTracker::GetInstanceForCurrentThread() | |
152 ->PopPseudoStackFrame(trace_event.name()); | |
153 } | |
154 } | |
155 return true; | |
156 } | |
157 | |
158 void EndEvent(const char* name, const char* category_group) override { | |
159 AllocationContextTracker::GetInstanceForCurrentThread() | |
160 ->PopPseudoStackFrame(name); | |
161 } | |
162 }; | |
163 | |
136 TraceLog::TraceEventFilterConstructorForTesting | 164 TraceLog::TraceEventFilterConstructorForTesting |
137 g_trace_event_filter_constructor_for_testing = nullptr; | 165 g_trace_event_filter_constructor_for_testing = nullptr; |
138 | 166 |
139 // Indexes here have to match the g_category_groups array indexes above. | 167 // Indexes here have to match the g_category_groups array indexes above. |
140 const int kCategoryAlreadyShutdown = 1; | 168 const int kCategoryAlreadyShutdown = 1; |
141 const int kCategoryCategoriesExhausted = 2; | 169 const int kCategoryCategoriesExhausted = 2; |
142 const int kCategoryMetadata = 3; | 170 const int kCategoryMetadata = 3; |
143 const int kNumBuiltinCategories = 4; | 171 const int kNumBuiltinCategories = 4; |
144 // Skip default categories. | 172 // Skip default categories. |
145 base::subtle::AtomicWord g_category_index = kNumBuiltinCategories; | 173 base::subtle::AtomicWord g_category_index = kNumBuiltinCategories; |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
532 | 560 |
533 // Having a filter is an exceptional case, so we avoid | 561 // Having a filter is an exceptional case, so we avoid |
534 // the LazyInstance creation in the common case. | 562 // the LazyInstance creation in the common case. |
535 if (!(g_category_group_filter[category_index] == nullptr)) | 563 if (!(g_category_group_filter[category_index] == nullptr)) |
536 g_category_group_filter[category_index].Get().clear(); | 564 g_category_group_filter[category_index].Get().clear(); |
537 | 565 |
538 for (const auto& event_filter : trace_config_.event_filters()) { | 566 for (const auto& event_filter : trace_config_.event_filters()) { |
539 if (event_filter.IsCategoryGroupEnabled(category_group)) { | 567 if (event_filter.IsCategoryGroupEnabled(category_group)) { |
540 std::unique_ptr<TraceEventFilter> new_filter; | 568 std::unique_ptr<TraceEventFilter> new_filter; |
541 | 569 |
542 if (event_filter.predicate_name() == "event_whitelist_predicate") { | 570 if (event_filter.predicate_name() == |
571 TraceEventFilter::kEventWhitelistPredicate) { | |
543 new_filter = | 572 new_filter = |
544 WrapUnique(new EventNameFilter(event_filter.filter_args())); | 573 WrapUnique(new EventNameFilter(event_filter.filter_args())); |
574 } else if (event_filter.predicate_name() == | |
575 TraceEventFilter::kHeapProfilerPredicate) { | |
576 new_filter = WrapUnique(new HeapProfilerFilter()); | |
oystein (OOO til 10th of July)
2016/08/23 17:42:42
nit: Recently learned from chromium-dev that MakeU
ssid
2016/08/24 18:01:25
Done.
| |
545 } else if (event_filter.predicate_name() == "testing_predicate") { | 577 } else if (event_filter.predicate_name() == "testing_predicate") { |
546 CHECK(g_trace_event_filter_constructor_for_testing); | 578 CHECK(g_trace_event_filter_constructor_for_testing); |
547 new_filter = g_trace_event_filter_constructor_for_testing(); | 579 new_filter = g_trace_event_filter_constructor_for_testing(); |
548 } | 580 } |
549 | 581 |
550 if (new_filter) { | 582 if (new_filter) { |
551 g_category_group_filter[category_index].Get().push_back( | 583 g_category_group_filter[category_index].Get().push_back( |
552 std::move(new_filter)); | 584 std::move(new_filter)); |
553 enabled_flag |= ENABLED_FOR_FILTERING; | 585 enabled_flag |= ENABLED_FOR_FILTERING; |
554 } | 586 } |
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1335 // This is done sooner rather than later, to avoid creating the event and | 1367 // This is done sooner rather than later, to avoid creating the event and |
1336 // acquiring the lock, which is not needed for ETW as it's already threadsafe. | 1368 // acquiring the lock, which is not needed for ETW as it's already threadsafe. |
1337 if (*category_group_enabled & ENABLED_FOR_ETW_EXPORT) | 1369 if (*category_group_enabled & ENABLED_FOR_ETW_EXPORT) |
1338 TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id, | 1370 TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id, |
1339 num_args, arg_names, arg_types, arg_values, | 1371 num_args, arg_names, arg_types, arg_values, |
1340 convertable_values); | 1372 convertable_values); |
1341 #endif // OS_WIN | 1373 #endif // OS_WIN |
1342 | 1374 |
1343 std::string console_message; | 1375 std::string console_message; |
1344 std::unique_ptr<TraceEvent> filtered_trace_event; | 1376 std::unique_ptr<TraceEvent> filtered_trace_event; |
1377 bool disabled_by_filters = false; | |
1345 if (*category_group_enabled & ENABLED_FOR_FILTERING) { | 1378 if (*category_group_enabled & ENABLED_FOR_FILTERING) { |
1346 std::unique_ptr<TraceEvent> new_trace_event(new TraceEvent); | 1379 std::unique_ptr<TraceEvent> new_trace_event(new TraceEvent); |
1347 new_trace_event->Initialize(thread_id, offset_event_timestamp, thread_now, | 1380 new_trace_event->Initialize(thread_id, offset_event_timestamp, thread_now, |
1348 phase, category_group_enabled, name, scope, id, | 1381 phase, category_group_enabled, name, scope, id, |
1349 bind_id, num_args, arg_names, arg_types, | 1382 bind_id, num_args, arg_names, arg_types, |
1350 arg_values, convertable_values, flags); | 1383 arg_values, convertable_values, flags); |
1351 | 1384 |
1352 auto filter_list = GetCategoryGroupFilter(category_group_enabled); | 1385 auto filter_list = GetCategoryGroupFilter(category_group_enabled); |
1353 DCHECK(!filter_list->empty()); | 1386 DCHECK(!filter_list->empty()); |
1354 | 1387 |
1355 bool should_add_event = false; | 1388 disabled_by_filters = true; |
1356 for (const auto& trace_event_filter : *filter_list) { | 1389 for (const auto& trace_event_filter : *filter_list) { |
1357 if (trace_event_filter->FilterTraceEvent(*new_trace_event)) | 1390 if (trace_event_filter->FilterTraceEvent(*new_trace_event)) |
1358 should_add_event = true; | 1391 disabled_by_filters = false; |
1359 } | 1392 } |
1360 | 1393 |
1361 if (should_add_event) | 1394 if (!disabled_by_filters) |
1362 filtered_trace_event = std::move(new_trace_event); | 1395 filtered_trace_event = std::move(new_trace_event); |
1363 } | 1396 } |
1364 | 1397 |
1365 // Add the trace event if we're either *just* recording (and not filtering) | 1398 // If enabled for recording, the event should be added only if one of the |
1366 // or if we one of our filters indicates the event should be added. | 1399 // filters indicates or if category is not enabled for filtering. |
1367 if (((*category_group_enabled & ENABLED_FOR_RECORDING) && | 1400 if ((*category_group_enabled & ENABLED_FOR_RECORDING) && |
1368 (*category_group_enabled & ENABLED_FOR_FILTERING) == 0) || | 1401 !disabled_by_filters) { |
1369 filtered_trace_event) { | |
1370 OptionalAutoLock lock(&lock_); | 1402 OptionalAutoLock lock(&lock_); |
1371 | 1403 |
1372 TraceEvent* trace_event = NULL; | 1404 TraceEvent* trace_event = NULL; |
1373 if (thread_local_event_buffer) { | 1405 if (thread_local_event_buffer) { |
1374 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); | 1406 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); |
1375 } else { | 1407 } else { |
1376 lock.EnsureAcquired(); | 1408 lock.EnsureAcquired(); |
1377 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); | 1409 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); |
1378 } | 1410 } |
1379 | 1411 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1422 subtle::NoBarrier_Load(&event_callback_)); | 1454 subtle::NoBarrier_Load(&event_callback_)); |
1423 if (event_callback) { | 1455 if (event_callback) { |
1424 event_callback( | 1456 event_callback( |
1425 offset_event_timestamp, | 1457 offset_event_timestamp, |
1426 phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase, | 1458 phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase, |
1427 category_group_enabled, name, scope, id, num_args, arg_names, | 1459 category_group_enabled, name, scope, id, num_args, arg_names, |
1428 arg_types, arg_values, flags); | 1460 arg_types, arg_values, flags); |
1429 } | 1461 } |
1430 } | 1462 } |
1431 | 1463 |
1432 // TODO(primiano): Add support for events with copied name crbug.com/581078 | |
1433 if (!(flags & TRACE_EVENT_FLAG_COPY)) { | |
1434 if (AllocationContextTracker::capture_mode() == | |
1435 AllocationContextTracker::CaptureMode::PSEUDO_STACK) { | |
1436 if (phase == TRACE_EVENT_PHASE_BEGIN || | |
1437 phase == TRACE_EVENT_PHASE_COMPLETE) { | |
1438 AllocationContextTracker::GetInstanceForCurrentThread() | |
1439 ->PushPseudoStackFrame(name); | |
1440 } else if (phase == TRACE_EVENT_PHASE_END) { | |
1441 // The pop for |TRACE_EVENT_PHASE_COMPLETE| events | |
1442 // is in |TraceLog::UpdateTraceEventDuration|. | |
1443 AllocationContextTracker::GetInstanceForCurrentThread() | |
1444 ->PopPseudoStackFrame(name); | |
1445 } | |
1446 } | |
1447 } | |
1448 | |
1449 return handle; | 1464 return handle; |
1450 } | 1465 } |
1451 | 1466 |
1452 void TraceLog::AddMetadataEvent( | 1467 void TraceLog::AddMetadataEvent( |
1453 const unsigned char* category_group_enabled, | 1468 const unsigned char* category_group_enabled, |
1454 const char* name, | 1469 const char* name, |
1455 int num_args, | 1470 int num_args, |
1456 const char** arg_names, | 1471 const char** arg_names, |
1457 const unsigned char* arg_types, | 1472 const unsigned char* arg_types, |
1458 const unsigned long long* arg_values, | 1473 const unsigned long long* arg_values, |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1570 trace_event->UpdateDuration(now, thread_now); | 1585 trace_event->UpdateDuration(now, thread_now); |
1571 #if defined(OS_ANDROID) | 1586 #if defined(OS_ANDROID) |
1572 trace_event->SendToATrace(); | 1587 trace_event->SendToATrace(); |
1573 #endif | 1588 #endif |
1574 } | 1589 } |
1575 | 1590 |
1576 if (trace_options() & kInternalEchoToConsole) { | 1591 if (trace_options() & kInternalEchoToConsole) { |
1577 console_message = | 1592 console_message = |
1578 EventToConsoleMessage(TRACE_EVENT_PHASE_END, now, trace_event); | 1593 EventToConsoleMessage(TRACE_EVENT_PHASE_END, now, trace_event); |
1579 } | 1594 } |
1580 | |
1581 if (AllocationContextTracker::capture_mode() == | |
1582 AllocationContextTracker::CaptureMode::PSEUDO_STACK) { | |
1583 // The corresponding push is in |AddTraceEventWithThreadIdAndTimestamp|. | |
1584 AllocationContextTracker::GetInstanceForCurrentThread() | |
1585 ->PopPseudoStackFrame(name); | |
1586 } | |
1587 } | 1595 } |
1588 | 1596 |
1589 if (!console_message.empty()) | 1597 if (!console_message.empty()) |
1590 LOG(ERROR) << console_message; | 1598 LOG(ERROR) << console_message; |
1591 | 1599 |
1592 if (category_group_enabled_local & ENABLED_FOR_EVENT_CALLBACK) { | 1600 if (category_group_enabled_local & ENABLED_FOR_EVENT_CALLBACK) { |
1593 EventCallback event_callback = reinterpret_cast<EventCallback>( | 1601 EventCallback event_callback = reinterpret_cast<EventCallback>( |
1594 subtle::NoBarrier_Load(&event_callback_)); | 1602 subtle::NoBarrier_Load(&event_callback_)); |
1595 if (event_callback) { | 1603 if (event_callback) { |
1596 event_callback( | 1604 event_callback( |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1884 } | 1892 } |
1885 | 1893 |
1886 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 1894 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
1887 if (*category_group_enabled_) { | 1895 if (*category_group_enabled_) { |
1888 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, | 1896 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, |
1889 event_handle_); | 1897 event_handle_); |
1890 } | 1898 } |
1891 } | 1899 } |
1892 | 1900 |
1893 } // namespace trace_event_internal | 1901 } // namespace trace_event_internal |
OLD | NEW |