OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/debug/trace_event_impl.h" | 5 #include "base/debug/trace_event_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/debug/leak_annotations.h" | 10 #include "base/debug/leak_annotations.h" |
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 if (!(ret & RECORD_UNTIL_FULL) && !(ret & RECORD_CONTINUOUSLY)) | 771 if (!(ret & RECORD_UNTIL_FULL) && !(ret & RECORD_CONTINUOUSLY)) |
772 ret |= RECORD_UNTIL_FULL; // Default when no options are specified. | 772 ret |= RECORD_UNTIL_FULL; // Default when no options are specified. |
773 | 773 |
774 return static_cast<Options>(ret); | 774 return static_cast<Options>(ret); |
775 } | 775 } |
776 | 776 |
777 TraceLog::TraceLog() | 777 TraceLog::TraceLog() |
778 : enable_count_(0), | 778 : enable_count_(0), |
779 num_traces_recorded_(0), | 779 num_traces_recorded_(0), |
780 dispatching_to_observer_list_(false), | 780 dispatching_to_observer_list_(false), |
| 781 process_sort_index_(0), |
781 watch_category_(NULL), | 782 watch_category_(NULL), |
782 trace_options_(RECORD_UNTIL_FULL), | 783 trace_options_(RECORD_UNTIL_FULL), |
783 sampling_thread_handle_(0), | 784 sampling_thread_handle_(0), |
784 category_filter_(CategoryFilter::kDefaultCategoryFilterString) { | 785 category_filter_(CategoryFilter::kDefaultCategoryFilterString) { |
785 // Trace is enabled or disabled on one thread while other threads are | 786 // Trace is enabled or disabled on one thread while other threads are |
786 // accessing the enabled flag. We don't care whether edge-case events are | 787 // accessing the enabled flag. We don't care whether edge-case events are |
787 // traced or not, so we allow races on the enabled flag to keep the trace | 788 // traced or not, so we allow races on the enabled flag to keep the trace |
788 // macros fast. | 789 // macros fast. |
789 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: | 790 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: |
790 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, | 791 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 lock_.Acquire(); | 1008 lock_.Acquire(); |
1008 sampling_thread_handle_ = PlatformThreadHandle(); | 1009 sampling_thread_handle_ = PlatformThreadHandle(); |
1009 sampling_thread_.reset(); | 1010 sampling_thread_.reset(); |
1010 } | 1011 } |
1011 | 1012 |
1012 category_filter_.Clear(); | 1013 category_filter_.Clear(); |
1013 watch_category_ = NULL; | 1014 watch_category_ = NULL; |
1014 watch_event_name_ = ""; | 1015 watch_event_name_ = ""; |
1015 for (int i = 0; i < g_category_index; i++) | 1016 for (int i = 0; i < g_category_index; i++) |
1016 SetCategoryGroupEnabled(i, false); | 1017 SetCategoryGroupEnabled(i, false); |
1017 AddThreadNameMetadataEvents(); | 1018 AddMetadataEvents(); |
1018 | 1019 |
1019 dispatching_to_observer_list_ = true; | 1020 dispatching_to_observer_list_ = true; |
1020 observer_list = enabled_state_observer_list_; | 1021 observer_list = enabled_state_observer_list_; |
1021 } | 1022 } |
1022 | 1023 |
1023 // Dispatch to observers outside the lock in case the observer triggers a | 1024 // Dispatch to observers outside the lock in case the observer triggers a |
1024 // trace event. | 1025 // trace event. |
1025 for (size_t i = 0; i < observer_list.size(); ++i) | 1026 for (size_t i = 0; i < observer_list.size(); ++i) |
1026 observer_list[i]->OnTraceLogDisabled(); | 1027 observer_list[i]->OnTraceLogDisabled(); |
1027 | 1028 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 notifier.SendNotificationIfAny(); | 1291 notifier.SendNotificationIfAny(); |
1291 } | 1292 } |
1292 } | 1293 } |
1293 | 1294 |
1294 void TraceLog::CancelWatchEvent() { | 1295 void TraceLog::CancelWatchEvent() { |
1295 AutoLock lock(lock_); | 1296 AutoLock lock(lock_); |
1296 watch_category_ = NULL; | 1297 watch_category_ = NULL; |
1297 watch_event_name_ = ""; | 1298 watch_event_name_ = ""; |
1298 } | 1299 } |
1299 | 1300 |
1300 void TraceLog::AddThreadNameMetadataEvents() { | 1301 namespace { |
| 1302 |
| 1303 template <typename T> |
| 1304 void AddMetadataEventToBuffer( |
| 1305 TraceBuffer* logged_events, |
| 1306 int thread_id, |
| 1307 const char* metadata_name, const char* arg_name, |
| 1308 const T& value) { |
| 1309 int num_args = 1; |
| 1310 unsigned char arg_type; |
| 1311 unsigned long long arg_value; |
| 1312 trace_event_internal::SetTraceValue(value, &arg_type, &arg_value); |
| 1313 logged_events->AddEvent(TraceEvent( |
| 1314 thread_id, |
| 1315 TimeTicks(), TRACE_EVENT_PHASE_METADATA, |
| 1316 &g_category_group_enabled[g_category_metadata], |
| 1317 metadata_name, trace_event_internal::kNoEventId, |
| 1318 num_args, &arg_name, &arg_type, &arg_value, NULL, |
| 1319 TRACE_EVENT_FLAG_NONE)); |
| 1320 } |
| 1321 |
| 1322 } |
| 1323 |
| 1324 void TraceLog::AddMetadataEvents() { |
1301 lock_.AssertAcquired(); | 1325 lock_.AssertAcquired(); |
| 1326 |
| 1327 int current_thread_id = static_cast<int>(base::PlatformThread::CurrentId()); |
| 1328 if (process_sort_index_ != 0) { |
| 1329 AddMetadataEventToBuffer(logged_events_.get(), |
| 1330 current_thread_id, |
| 1331 "process_sort_index", "sort_index", |
| 1332 process_sort_index_); |
| 1333 } |
| 1334 |
| 1335 if (process_name_.size()) { |
| 1336 AddMetadataEventToBuffer(logged_events_.get(), |
| 1337 current_thread_id, |
| 1338 "process_name", "name", |
| 1339 process_name_); |
| 1340 } |
| 1341 |
| 1342 if (process_labels_.size() > 0) { |
| 1343 std::vector<std::string> labels; |
| 1344 for(base::hash_map<int, std::string>::iterator it = process_labels_.begin(); |
| 1345 it != process_labels_.end(); |
| 1346 it++) { |
| 1347 labels.push_back(it->second); |
| 1348 } |
| 1349 AddMetadataEventToBuffer(logged_events_.get(), |
| 1350 current_thread_id, |
| 1351 "process_labels", "labels", |
| 1352 JoinString(labels, ',')); |
| 1353 } |
| 1354 |
| 1355 // Thread sort indices. |
| 1356 for(hash_map<int, int>::iterator it = thread_sort_indices_.begin(); |
| 1357 it != thread_sort_indices_.end(); |
| 1358 it++) { |
| 1359 if (it->second == 0) |
| 1360 continue; |
| 1361 AddMetadataEventToBuffer(logged_events_.get(), |
| 1362 it->first, |
| 1363 "thread_sort_index", "sort_index", |
| 1364 it->second); |
| 1365 } |
| 1366 |
| 1367 // Thread names. |
1302 for(hash_map<int, std::string>::iterator it = thread_names_.begin(); | 1368 for(hash_map<int, std::string>::iterator it = thread_names_.begin(); |
1303 it != thread_names_.end(); | 1369 it != thread_names_.end(); |
1304 it++) { | 1370 it++) { |
1305 if (!it->second.empty()) { | 1371 if (it->second.empty()) |
1306 int num_args = 1; | 1372 continue; |
1307 const char* arg_name = "name"; | 1373 AddMetadataEventToBuffer(logged_events_.get(), |
1308 unsigned char arg_type; | 1374 it->first, |
1309 unsigned long long arg_value; | 1375 "thread_name", "name", |
1310 trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value); | 1376 it->second); |
1311 logged_events_->AddEvent(TraceEvent(it->first, | |
1312 TimeTicks(), TRACE_EVENT_PHASE_METADATA, | |
1313 &g_category_group_enabled[g_category_metadata], | |
1314 "thread_name", trace_event_internal::kNoEventId, | |
1315 num_args, &arg_name, &arg_type, &arg_value, NULL, | |
1316 TRACE_EVENT_FLAG_NONE)); | |
1317 } | |
1318 } | 1377 } |
1319 } | 1378 } |
1320 | 1379 |
1321 void TraceLog::InstallWaitableEventForSamplingTesting( | 1380 void TraceLog::InstallWaitableEventForSamplingTesting( |
1322 WaitableEvent* waitable_event) { | 1381 WaitableEvent* waitable_event) { |
1323 sampling_thread_->InstallWaitableEventForSamplingTesting(waitable_event); | 1382 sampling_thread_->InstallWaitableEventForSamplingTesting(waitable_event); |
1324 } | 1383 } |
1325 | 1384 |
1326 void TraceLog::DeleteForTesting() { | 1385 void TraceLog::DeleteForTesting() { |
1327 DeleteTraceLogForTesting::Delete(); | 1386 DeleteTraceLogForTesting::Delete(); |
1328 } | 1387 } |
1329 | 1388 |
1330 void TraceLog::Resurrect() { | 1389 void TraceLog::Resurrect() { |
1331 StaticMemorySingletonTraits<TraceLog>::Resurrect(); | 1390 StaticMemorySingletonTraits<TraceLog>::Resurrect(); |
1332 } | 1391 } |
1333 | 1392 |
1334 void TraceLog::SetProcessID(int process_id) { | 1393 void TraceLog::SetProcessID(int process_id) { |
1335 process_id_ = process_id; | 1394 process_id_ = process_id; |
1336 // Create a FNV hash from the process ID for XORing. | 1395 // Create a FNV hash from the process ID for XORing. |
1337 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details. | 1396 // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details. |
1338 unsigned long long offset_basis = 14695981039346656037ull; | 1397 unsigned long long offset_basis = 14695981039346656037ull; |
1339 unsigned long long fnv_prime = 1099511628211ull; | 1398 unsigned long long fnv_prime = 1099511628211ull; |
1340 unsigned long long pid = static_cast<unsigned long long>(process_id_); | 1399 unsigned long long pid = static_cast<unsigned long long>(process_id_); |
1341 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; | 1400 process_id_hash_ = (offset_basis ^ pid) * fnv_prime; |
1342 } | 1401 } |
1343 | 1402 |
| 1403 void TraceLog::SetProcessSortIndex(int sort_index) { |
| 1404 AutoLock lock(lock_); |
| 1405 process_sort_index_ = sort_index; |
| 1406 } |
| 1407 |
| 1408 void TraceLog::SetProcessName(const std::string& process_name) { |
| 1409 AutoLock lock(lock_); |
| 1410 process_name_ = process_name; |
| 1411 } |
| 1412 |
| 1413 void TraceLog::UpdateProcessLabel( |
| 1414 int label_id, const std::string& current_label) { |
| 1415 if(!current_label.length()) |
| 1416 return RemoveProcessLabel(label_id); |
| 1417 |
| 1418 AutoLock lock(lock_); |
| 1419 process_labels_[label_id] = current_label; |
| 1420 } |
| 1421 |
| 1422 void TraceLog::RemoveProcessLabel(int label_id) { |
| 1423 base::hash_map<int, std::string>::iterator it = process_labels_.find( |
| 1424 label_id); |
| 1425 if (it == process_labels_.end()) |
| 1426 return; |
| 1427 |
| 1428 process_labels_.erase(it); |
| 1429 } |
| 1430 |
| 1431 void TraceLog::SetThreadSortIndex(PlatformThreadId thread_id, int sort_index) { |
| 1432 AutoLock lock(lock_); |
| 1433 thread_sort_indices_[static_cast<int>(thread_id)] = sort_index; |
| 1434 } |
| 1435 |
1344 void TraceLog::SetTimeOffset(TimeDelta offset) { | 1436 void TraceLog::SetTimeOffset(TimeDelta offset) { |
1345 time_offset_ = offset; | 1437 time_offset_ = offset; |
1346 } | 1438 } |
1347 | 1439 |
1348 size_t TraceLog::GetObserverCountForTest() const { | 1440 size_t TraceLog::GetObserverCountForTest() const { |
1349 return enabled_state_observer_list_.size(); | 1441 return enabled_state_observer_list_.size(); |
1350 } | 1442 } |
1351 | 1443 |
1352 bool CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( | 1444 bool CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( |
1353 const std::string& str) { | 1445 const std::string& str) { |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 0, // num_args | 1641 0, // num_args |
1550 NULL, // arg_names | 1642 NULL, // arg_names |
1551 NULL, // arg_types | 1643 NULL, // arg_types |
1552 NULL, // arg_values | 1644 NULL, // arg_values |
1553 NULL, // convertable values | 1645 NULL, // convertable values |
1554 TRACE_EVENT_FLAG_NONE); // flags | 1646 TRACE_EVENT_FLAG_NONE); // flags |
1555 } | 1647 } |
1556 } | 1648 } |
1557 | 1649 |
1558 } // namespace trace_event_internal | 1650 } // namespace trace_event_internal |
OLD | NEW |