Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: base/debug/trace_event_impl.cc

Issue 17451017: Process names, and predictable thread and process ordering in about:tracing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updates, most nits addresssed Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698