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 |