| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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.h" | 5 #include "base/debug/trace_event.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
| 10 #include "base/debug/trace_event_win.h" | 10 #include "base/debug/trace_event_win.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 *out += temp_string; | 76 *out += temp_string; |
| 77 break; | 77 break; |
| 78 case TRACE_TYPE_POINTER: | 78 case TRACE_TYPE_POINTER: |
| 79 base::snprintf(temp_string, arraysize(temp_string), "%llu", | 79 base::snprintf(temp_string, arraysize(temp_string), "%llu", |
| 80 static_cast<unsigned long long>( | 80 static_cast<unsigned long long>( |
| 81 reinterpret_cast<intptr_t>( | 81 reinterpret_cast<intptr_t>( |
| 82 as_pointer()))); | 82 as_pointer()))); |
| 83 *out += temp_string; | 83 *out += temp_string; |
| 84 break; | 84 break; |
| 85 case TRACE_TYPE_STRING: | 85 case TRACE_TYPE_STRING: |
| 86 case TRACE_TYPE_STATIC_STRING: |
| 86 *out += "\""; | 87 *out += "\""; |
| 87 start_pos = out->size(); | 88 start_pos = out->size(); |
| 88 *out += as_string(); | 89 *out += as_string() ? as_string() : "NULL"; |
| 89 // replace " character with ' | 90 // replace " character with ' |
| 90 while ((start_pos = out->find_first_of('\"', start_pos)) != | 91 while ((start_pos = out->find_first_of('\"', start_pos)) != |
| 91 std::string::npos) | 92 std::string::npos) |
| 92 (*out)[start_pos] = '\''; | 93 (*out)[start_pos] = '\''; |
| 93 *out += "\""; | 94 *out += "\""; |
| 94 break; | 95 break; |
| 95 default: | 96 default: |
| 96 NOTREACHED() << "Don't know how to print this value"; | 97 NOTREACHED() << "Don't know how to print this value"; |
| 97 break; | 98 break; |
| 98 } | 99 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 arg_names_[1] = arg2_name; | 170 arg_names_[1] = arg2_name; |
| 170 arg_values_[0] = arg1_val; | 171 arg_values_[0] = arg1_val; |
| 171 arg_values_[1] = arg2_val; | 172 arg_values_[1] = arg2_val; |
| 172 | 173 |
| 173 size_t alloc_size = 0; | 174 size_t alloc_size = 0; |
| 174 if (copy) { | 175 if (copy) { |
| 175 alloc_size += GetAllocLength(name); | 176 alloc_size += GetAllocLength(name); |
| 176 alloc_size += GetAllocLength(arg1_name); | 177 alloc_size += GetAllocLength(arg1_name); |
| 177 alloc_size += GetAllocLength(arg2_name); | 178 alloc_size += GetAllocLength(arg2_name); |
| 178 } | 179 } |
| 179 // We always take a copy of string arg_vals, even if |copy| was not set. | 180 |
| 180 if (arg1_val.type() == TraceValue::TRACE_TYPE_STRING) | 181 bool arg1_is_copy = (arg1_val.type() == TraceValue::TRACE_TYPE_STRING); |
| 182 bool arg2_is_copy = (arg2_val.type() == TraceValue::TRACE_TYPE_STRING); |
| 183 |
| 184 // We only take a copy of arg_vals if they are of type string (not static |
| 185 // string), regardless of the |copy| flag. |
| 186 if (arg1_is_copy) |
| 181 alloc_size += GetAllocLength(arg1_val.as_string()); | 187 alloc_size += GetAllocLength(arg1_val.as_string()); |
| 182 if (arg2_val.type() == TraceValue::TRACE_TYPE_STRING) | 188 if (arg2_is_copy) |
| 183 alloc_size += GetAllocLength(arg2_val.as_string()); | 189 alloc_size += GetAllocLength(arg2_val.as_string()); |
| 184 | 190 |
| 185 if (alloc_size) { | 191 if (alloc_size) { |
| 186 parameter_copy_storage_ = new base::RefCountedString; | 192 parameter_copy_storage_ = new base::RefCountedString; |
| 187 parameter_copy_storage_->data().resize(alloc_size); | 193 parameter_copy_storage_->data().resize(alloc_size); |
| 188 char* ptr = string_as_array(¶meter_copy_storage_->data()); | 194 char* ptr = string_as_array(¶meter_copy_storage_->data()); |
| 189 const char* end = ptr + alloc_size; | 195 const char* end = ptr + alloc_size; |
| 190 if (copy) { | 196 if (copy) { |
| 191 CopyTraceEventParameter(&ptr, &name_, end); | 197 CopyTraceEventParameter(&ptr, &name_, end); |
| 192 CopyTraceEventParameter(&ptr, &arg_names_[0], end); | 198 CopyTraceEventParameter(&ptr, &arg_names_[0], end); |
| 193 CopyTraceEventParameter(&ptr, &arg_names_[1], end); | 199 CopyTraceEventParameter(&ptr, &arg_names_[1], end); |
| 194 } | 200 } |
| 195 if (arg_values_[0].type() == TraceValue::TRACE_TYPE_STRING) | 201 if (arg1_is_copy) |
| 196 CopyTraceEventParameter(&ptr, arg_values_[0].as_assignable_string(), end); | 202 CopyTraceEventParameter(&ptr, arg_values_[0].as_assignable_string(), end); |
| 197 if (arg_values_[1].type() == TraceValue::TRACE_TYPE_STRING) | 203 if (arg2_is_copy) |
| 198 CopyTraceEventParameter(&ptr, arg_values_[1].as_assignable_string(), end); | 204 CopyTraceEventParameter(&ptr, arg_values_[1].as_assignable_string(), end); |
| 199 DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end; | 205 DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end; |
| 200 } | 206 } |
| 201 } | 207 } |
| 202 | 208 |
| 203 TraceEvent::~TraceEvent() { | 209 TraceEvent::~TraceEvent() { |
| 204 } | 210 } |
| 205 | 211 |
| 206 void TraceEvent::AppendEventsAsJSON(const std::vector<TraceEvent>& events, | 212 void TraceEvent::AppendEventsAsJSON(const std::vector<TraceEvent>& events, |
| 207 size_t start, | 213 size_t start, |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 } | 361 } |
| 356 } | 362 } |
| 357 | 363 |
| 358 int TraceLog::AddTraceEvent(TraceEventPhase phase, | 364 int TraceLog::AddTraceEvent(TraceEventPhase phase, |
| 359 const TraceCategory* category, | 365 const TraceCategory* category, |
| 360 const char* name, | 366 const char* name, |
| 361 const char* arg1_name, TraceValue arg1_val, | 367 const char* arg1_name, TraceValue arg1_val, |
| 362 const char* arg2_name, TraceValue arg2_val, | 368 const char* arg2_name, TraceValue arg2_val, |
| 363 int threshold_begin_id, | 369 int threshold_begin_id, |
| 364 int64 threshold, | 370 int64 threshold, |
| 365 bool copy) { | 371 EventFlags flags) { |
| 366 DCHECK(name); | 372 DCHECK(name); |
| 367 #ifdef USE_UNRELIABLE_NOW | 373 #ifdef USE_UNRELIABLE_NOW |
| 368 TimeTicks now = TimeTicks::HighResNow(); | 374 TimeTicks now = TimeTicks::HighResNow(); |
| 369 #else | 375 #else |
| 370 TimeTicks now = TimeTicks::Now(); | 376 TimeTicks now = TimeTicks::Now(); |
| 371 #endif | 377 #endif |
| 372 BufferFullCallback buffer_full_callback_copy; | 378 BufferFullCallback buffer_full_callback_copy; |
| 373 int ret_begin_id = -1; | 379 int ret_begin_id = -1; |
| 374 { | 380 { |
| 375 AutoLock lock(lock_); | 381 AutoLock lock(lock_); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 return -1; | 426 return -1; |
| 421 } | 427 } |
| 422 } | 428 } |
| 423 ret_begin_id = static_cast<int>(logged_events_.size()); | 429 ret_begin_id = static_cast<int>(logged_events_.size()); |
| 424 logged_events_.push_back( | 430 logged_events_.push_back( |
| 425 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), | 431 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), |
| 426 thread_id, | 432 thread_id, |
| 427 now, phase, category, name, | 433 now, phase, category, name, |
| 428 arg1_name, arg1_val, | 434 arg1_name, arg1_val, |
| 429 arg2_name, arg2_val, | 435 arg2_name, arg2_val, |
| 430 copy)); | 436 flags & EVENT_FLAG_COPY)); |
| 431 | 437 |
| 432 if (logged_events_.size() == kTraceEventBufferSize) { | 438 if (logged_events_.size() == kTraceEventBufferSize) { |
| 433 buffer_full_callback_copy = buffer_full_callback_; | 439 buffer_full_callback_copy = buffer_full_callback_; |
| 434 } | 440 } |
| 435 } // release lock | 441 } // release lock |
| 436 | 442 |
| 437 if (!buffer_full_callback_copy.is_null()) | 443 if (!buffer_full_callback_copy.is_null()) |
| 438 buffer_full_callback_copy.Run(); | 444 buffer_full_callback_copy.Run(); |
| 439 | 445 |
| 440 return ret_begin_id; | 446 return ret_begin_id; |
| 441 } | 447 } |
| 442 | 448 |
| 443 void TraceLog::AddTraceEventEtw(TraceEventPhase phase, | 449 void TraceLog::AddTraceEventEtw(TraceEventPhase phase, |
| 444 const char* name, | 450 const char* name, |
| 445 const void* id, | 451 const void* id, |
| 446 const char* extra) { | 452 const char* extra) { |
| 447 // Legacy trace points on windows called to ETW | |
| 448 #if defined(OS_WIN) | 453 #if defined(OS_WIN) |
| 449 TraceEventETWProvider::Trace(name, phase, id, extra); | 454 TraceEventETWProvider::Trace(name, phase, id, extra); |
| 450 #endif | 455 #endif |
| 456 INTERNAL_TRACE_EVENT_ADD(phase, |
| 457 "ETW Trace Event", name, "id", id, "extra", TRACE_STR_COPY(extra), |
| 458 base::debug::TraceLog::EVENT_FLAG_NONE); |
| 459 } |
| 451 | 460 |
| 452 // Also add new trace event behavior | 461 void TraceLog::AddTraceEventEtw(TraceEventPhase phase, |
| 453 static const TraceCategory* category = GetCategory("ETW Trace Event"); | 462 const char* name, |
| 454 if (category->enabled) { | 463 const void* id, |
| 455 TraceLog* tracelog = TraceLog::GetInstance(); | 464 const std::string& extra) |
| 456 if (!tracelog) | 465 { |
| 457 return; | 466 #if defined(OS_WIN) |
| 458 tracelog->AddTraceEvent(phase, category, name, | 467 TraceEventETWProvider::Trace(name, phase, id, extra); |
| 459 "id", id, | 468 #endif |
| 460 "extra", extra ? extra : "", | 469 INTERNAL_TRACE_EVENT_ADD(phase, |
| 461 -1, 0, false); | 470 "ETW Trace Event", name, "id", id, "extra", extra, |
| 462 } | 471 base::debug::TraceLog::EVENT_FLAG_NONE); |
| 463 } | 472 } |
| 464 | 473 |
| 465 void TraceLog::AddCurrentMetadataEvents() { | 474 void TraceLog::AddCurrentMetadataEvents() { |
| 466 lock_.AssertAcquired(); | 475 lock_.AssertAcquired(); |
| 467 for(base::hash_map<PlatformThreadId, std::string>::iterator it = | 476 for(base::hash_map<PlatformThreadId, std::string>::iterator it = |
| 468 thread_names_.begin(); | 477 thread_names_.begin(); |
| 469 it != thread_names_.end(); | 478 it != thread_names_.end(); |
| 470 it++) { | 479 it++) { |
| 471 if (!it->second.empty()) | 480 if (!it->second.empty()) |
| 472 logged_events_.push_back( | 481 logged_events_.push_back( |
| 473 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), | 482 TraceEvent(static_cast<unsigned long>(base::GetCurrentProcId()), |
| 474 it->first, | 483 it->first, |
| 475 TimeTicks(), base::debug::TRACE_EVENT_PHASE_METADATA, | 484 TimeTicks(), base::debug::TRACE_EVENT_PHASE_METADATA, |
| 476 g_category_metadata, "thread_name", | 485 g_category_metadata, "thread_name", |
| 477 "name", it->second.c_str(), | 486 "name", it->second, |
| 478 NULL, 0, | 487 NULL, 0, |
| 479 false)); | 488 false)); |
| 480 } | 489 } |
| 481 } | 490 } |
| 482 | 491 |
| 483 void TraceLog::Resurrect() { | 492 void TraceLog::Resurrect() { |
| 484 StaticMemorySingletonTraits<TraceLog>::Resurrect(); | 493 StaticMemorySingletonTraits<TraceLog>::Resurrect(); |
| 485 } | 494 } |
| 486 | 495 |
| 487 namespace internal { | 496 namespace internal { |
| 488 | 497 |
| 489 void TraceEndOnScopeClose::Initialize(const TraceCategory* category, | 498 void TraceEndOnScopeClose::Initialize(const TraceCategory* category, |
| 490 const char* name) { | 499 const char* name) { |
| 491 data_.category = category; | 500 data_.category = category; |
| 492 data_.name = name; | 501 data_.name = name; |
| 493 p_data_ = &data_; | 502 p_data_ = &data_; |
| 494 } | 503 } |
| 495 | 504 |
| 496 void TraceEndOnScopeClose::AddEventIfEnabled() { | 505 void TraceEndOnScopeClose::AddEventIfEnabled() { |
| 497 // Only called when p_data_ is non-null. | 506 // Only called when p_data_ is non-null. |
| 498 if (p_data_->category->enabled) { | 507 if (p_data_->category->enabled) { |
| 499 base::debug::TraceLog::GetInstance()->AddTraceEvent( | 508 base::debug::TraceLog::GetInstance()->AddTraceEvent( |
| 500 base::debug::TRACE_EVENT_PHASE_END, | 509 base::debug::TRACE_EVENT_PHASE_END, |
| 501 p_data_->category, | 510 p_data_->category, |
| 502 p_data_->name, | 511 p_data_->name, |
| 503 NULL, 0, NULL, 0, | 512 NULL, 0, NULL, 0, |
| 504 -1, 0, false); | 513 -1, 0, TraceLog::EVENT_FLAG_NONE); |
| 505 } | 514 } |
| 506 } | 515 } |
| 507 | 516 |
| 508 void TraceEndOnScopeCloseThreshold::Initialize(const TraceCategory* category, | 517 void TraceEndOnScopeCloseThreshold::Initialize(const TraceCategory* category, |
| 509 const char* name, | 518 const char* name, |
| 510 int threshold_begin_id, | 519 int threshold_begin_id, |
| 511 int64 threshold) { | 520 int64 threshold) { |
| 512 data_.category = category; | 521 data_.category = category; |
| 513 data_.name = name; | 522 data_.name = name; |
| 514 data_.threshold_begin_id = threshold_begin_id; | 523 data_.threshold_begin_id = threshold_begin_id; |
| 515 data_.threshold = threshold; | 524 data_.threshold = threshold; |
| 516 p_data_ = &data_; | 525 p_data_ = &data_; |
| 517 } | 526 } |
| 518 | 527 |
| 519 void TraceEndOnScopeCloseThreshold::AddEventIfEnabled() { | 528 void TraceEndOnScopeCloseThreshold::AddEventIfEnabled() { |
| 520 // Only called when p_data_ is non-null. | 529 // Only called when p_data_ is non-null. |
| 521 if (p_data_->category->enabled) { | 530 if (p_data_->category->enabled) { |
| 522 base::debug::TraceLog::GetInstance()->AddTraceEvent( | 531 base::debug::TraceLog::GetInstance()->AddTraceEvent( |
| 523 base::debug::TRACE_EVENT_PHASE_END, | 532 base::debug::TRACE_EVENT_PHASE_END, |
| 524 p_data_->category, | 533 p_data_->category, |
| 525 p_data_->name, | 534 p_data_->name, |
| 526 NULL, 0, NULL, 0, | 535 NULL, 0, NULL, 0, |
| 527 p_data_->threshold_begin_id, p_data_->threshold, false); | 536 p_data_->threshold_begin_id, p_data_->threshold, |
| 537 TraceLog::EVENT_FLAG_NONE); |
| 528 } | 538 } |
| 529 } | 539 } |
| 530 | 540 |
| 531 } // namespace internal | 541 } // namespace internal |
| 532 | 542 |
| 533 } // namespace debug | 543 } // namespace debug |
| 534 } // namespace base | 544 } // namespace base |
| OLD | NEW |