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