Chromium Code Reviews| 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 |