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

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

Issue 13590005: Add a ConvertableToTraceFormat type to the trace framework. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 8 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
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 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 TraceEvent::TraceEvent(int thread_id, 267 TraceEvent::TraceEvent(int thread_id,
268 TimeTicks timestamp, 268 TimeTicks timestamp,
269 char phase, 269 char phase,
270 const unsigned char* category_enabled, 270 const unsigned char* category_enabled,
271 const char* name, 271 const char* name,
272 unsigned long long id, 272 unsigned long long id,
273 int num_args, 273 int num_args,
274 const char** arg_names, 274 const char** arg_names,
275 const unsigned char* arg_types, 275 const unsigned char* arg_types,
276 const unsigned long long* arg_values, 276 const unsigned long long* arg_values,
277 scoped_ptr<ConvertableToJSON> convertable_values[],
277 unsigned char flags) 278 unsigned char flags)
278 : timestamp_(timestamp), 279 : timestamp_(timestamp),
279 id_(id), 280 id_(id),
280 category_enabled_(category_enabled), 281 category_enabled_(category_enabled),
281 name_(name), 282 name_(name),
282 thread_id_(thread_id), 283 thread_id_(thread_id),
283 phase_(phase), 284 phase_(phase),
284 flags_(flags) { 285 flags_(flags) {
285 // Clamp num_args since it may have been set by a third_party library. 286 // Clamp num_args since it may have been set by a third_party library.
286 num_args = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args; 287 num_args = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args;
287 int i = 0; 288 int i = 0;
288 for (; i < num_args; ++i) { 289 for (; i < num_args; ++i) {
289 arg_names_[i] = arg_names[i]; 290 arg_names_[i] = arg_names[i];
290 arg_values_[i].as_uint = arg_values[i];
291 arg_types_[i] = arg_types[i]; 291 arg_types_[i] = arg_types[i];
292
293 if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE)
294 convertable_values_[i].reset(convertable_values[i].release());
295 else
296 arg_values_[i].as_uint = arg_values[i];
292 } 297 }
293 for (; i < kTraceMaxNumArgs; ++i) { 298 for (; i < kTraceMaxNumArgs; ++i) {
294 arg_names_[i] = NULL; 299 arg_names_[i] = NULL;
295 arg_values_[i].as_uint = 0u; 300 arg_values_[i].as_uint = 0u;
301 convertable_values_[i].reset();
296 arg_types_[i] = TRACE_VALUE_TYPE_UINT; 302 arg_types_[i] = TRACE_VALUE_TYPE_UINT;
297 } 303 }
298 304
299 bool copy = !!(flags & TRACE_EVENT_FLAG_COPY); 305 bool copy = !!(flags & TRACE_EVENT_FLAG_COPY);
300 size_t alloc_size = 0; 306 size_t alloc_size = 0;
301 if (copy) { 307 if (copy) {
302 alloc_size += GetAllocLength(name); 308 alloc_size += GetAllocLength(name);
303 for (i = 0; i < num_args; ++i) { 309 for (i = 0; i < num_args; ++i) {
304 alloc_size += GetAllocLength(arg_names_[i]); 310 alloc_size += GetAllocLength(arg_names_[i]);
305 if (arg_types_[i] == TRACE_VALUE_TYPE_STRING) 311 if (arg_types_[i] == TRACE_VALUE_TYPE_STRING)
306 arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING; 312 arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING;
307 } 313 }
308 } 314 }
309 315
310 bool arg_is_copy[kTraceMaxNumArgs]; 316 bool arg_is_copy[kTraceMaxNumArgs];
311 for (i = 0; i < num_args; ++i) { 317 for (i = 0; i < num_args; ++i) {
318 // No copying of convertable types, we retain ownership.
319 if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
320 continue;
321
312 // We only take a copy of arg_vals if they are of type COPY_STRING. 322 // We only take a copy of arg_vals if they are of type COPY_STRING.
313 arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING); 323 arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING);
314 if (arg_is_copy[i]) 324 if (arg_is_copy[i])
315 alloc_size += GetAllocLength(arg_values_[i].as_string); 325 alloc_size += GetAllocLength(arg_values_[i].as_string);
316 } 326 }
317 327
318 if (alloc_size) { 328 if (alloc_size) {
319 parameter_copy_storage_ = new RefCountedString; 329 parameter_copy_storage_ = new RefCountedString;
320 parameter_copy_storage_->data().resize(alloc_size); 330 parameter_copy_storage_->data().resize(alloc_size);
321 char* ptr = string_as_array(&parameter_copy_storage_->data()); 331 char* ptr = string_as_array(&parameter_copy_storage_->data());
322 const char* end = ptr + alloc_size; 332 const char* end = ptr + alloc_size;
323 if (copy) { 333 if (copy) {
324 CopyTraceEventParameter(&ptr, &name_, end); 334 CopyTraceEventParameter(&ptr, &name_, end);
325 for (i = 0; i < num_args; ++i) 335 for (i = 0; i < num_args; ++i) {
336 if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
337 continue;
326 CopyTraceEventParameter(&ptr, &arg_names_[i], end); 338 CopyTraceEventParameter(&ptr, &arg_names_[i], end);
339 }
327 } 340 }
328 for (i = 0; i < num_args; ++i) { 341 for (i = 0; i < num_args; ++i) {
342 if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
343 continue;
329 if (arg_is_copy[i]) 344 if (arg_is_copy[i])
330 CopyTraceEventParameter(&ptr, &arg_values_[i].as_string, end); 345 CopyTraceEventParameter(&ptr, &arg_values_[i].as_string, end);
331 } 346 }
332 DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end; 347 DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end;
333 } 348 }
334 } 349 }
335 350
351 TraceEvent::TraceEvent(const TraceEvent& other)
352 : timestamp_(other.timestamp_),
353 id_(other.id_),
354 category_enabled_(other.category_enabled_),
355 name_(other.name_),
356 thread_id_(other.thread_id_),
357 phase_(other.phase_),
358 flags_(other.flags_) {
359 parameter_copy_storage_ = other.parameter_copy_storage_;
360
361 for (int i = 0; i < kTraceMaxNumArgs; ++i) {
362 arg_values_[i] = other.arg_values_[i];
363 arg_names_[i] = other.arg_names_[i];
364 arg_types_[i] = other.arg_types_[i];
365
366 if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
367 // TODO(dsinclair): Is this correct? We have to release the pointer from
368 // the other scoped_ptr so we can have it.
369 convertable_values_[i].reset(
370 const_cast<TraceEvent*>(&other)->convertable_values_[i].release());
371 } else {
372 convertable_values_[i].reset();
373 }
374 }
375 }
376
377 TraceEvent& TraceEvent::operator=(const TraceEvent& other) {
378 if (this == &other)
379 return *this;
380
381 timestamp_ = other.timestamp_;
382 id_ = other.id_;
383 category_enabled_ = other.category_enabled_;
384 name_ = other.name_;
385 parameter_copy_storage_ = other.parameter_copy_storage_;
386 thread_id_ = other.thread_id_;
387 phase_ = other.phase_;
388 flags_ = other.flags_;
389
390 for (int i = 0; i < kTraceMaxNumArgs; ++i) {
391 arg_values_[i] = other.arg_values_[i];
392 arg_names_[i] = other.arg_names_[i];
393 arg_types_[i] = other.arg_types_[i];
394
395 if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) {
396 // TODO(dsinclair): Is this correct? We have to release the pointer from
397 // the other scoped_ptr so we can have it.
398 convertable_values_[i].reset(
399 const_cast<TraceEvent*>(&other)->convertable_values_[i].release());
400 } else {
401 convertable_values_[i].reset();
402 }
403 }
404 return *this;
405 }
406
336 TraceEvent::~TraceEvent() { 407 TraceEvent::~TraceEvent() {
337 } 408 }
338 409
339 // static 410 // static
340 void TraceEvent::AppendValueAsJSON(unsigned char type, 411 void TraceEvent::AppendValueAsJSON(unsigned char type,
341 TraceEvent::TraceValue value, 412 TraceEvent::TraceValue value,
342 std::string* out) { 413 std::string* out) {
343 std::string::size_type start_pos; 414 std::string::size_type start_pos;
344 switch (type) { 415 switch (type) {
345 case TRACE_VALUE_TYPE_BOOL: 416 case TRACE_VALUE_TYPE_BOOL:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 phase_, 467 phase_,
397 name_); 468 name_);
398 469
399 // Output argument names and values, stop at first NULL argument name. 470 // Output argument names and values, stop at first NULL argument name.
400 for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) { 471 for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) {
401 if (i > 0) 472 if (i > 0)
402 *out += ","; 473 *out += ",";
403 *out += "\""; 474 *out += "\"";
404 *out += arg_names_[i]; 475 *out += arg_names_[i];
405 *out += "\":"; 476 *out += "\":";
406 AppendValueAsJSON(arg_types_[i], arg_values_[i], out); 477
478 if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE)
479 convertable_values_[i]->ToJSON(*out);
480 else
481 AppendValueAsJSON(arg_types_[i], arg_values_[i], out);
407 } 482 }
408 *out += "}"; 483 *out += "}";
409 484
410 // If id_ is set, print it out as a hex string so we don't loose any 485 // If id_ is set, print it out as a hex string so we don't loose any
411 // bits (it might be a 64-bit pointer). 486 // bits (it might be a 64-bit pointer).
412 if (flags_ & TRACE_EVENT_FLAG_HAS_ID) 487 if (flags_ & TRACE_EVENT_FLAG_HAS_ID)
413 StringAppendF(out, ",\"id\":\"%" PRIx64 "\"", static_cast<uint64>(id_)); 488 StringAppendF(out, ",\"id\":\"%" PRIx64 "\"", static_cast<uint64>(id_));
414 489
415 // Instant events also output their scope. 490 // Instant events also output their scope.
416 if (phase_ == TRACE_EVENT_PHASE_INSTANT) { 491 if (phase_ == TRACE_EVENT_PHASE_INSTANT) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data->bucket); 633 TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data->bucket);
559 if (!category_and_name) 634 if (!category_and_name)
560 return; 635 return;
561 const char* const combined = 636 const char* const combined =
562 reinterpret_cast<const char* const>(category_and_name); 637 reinterpret_cast<const char* const>(category_and_name);
563 const char* category; 638 const char* category;
564 const char* name; 639 const char* name;
565 ExtractCategoryAndName(combined, &category, &name); 640 ExtractCategoryAndName(combined, &category, &name);
566 TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SAMPLE, 641 TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SAMPLE,
567 TraceLog::GetCategoryEnabled(category), 642 TraceLog::GetCategoryEnabled(category),
568 name, 643 name, 0, 0, NULL, NULL, NULL, NULL, 0);
569 0,
570 0,
571 NULL,
572 NULL,
573 NULL,
574 0);
575 } 644 }
576 645
577 void TraceSamplingThread::GetSamples() { 646 void TraceSamplingThread::GetSamples() {
578 for (size_t i = 0; i < sample_buckets_.size(); ++i) { 647 for (size_t i = 0; i < sample_buckets_.size(); ++i) {
579 TraceBucketData* bucket_data = &sample_buckets_[i]; 648 TraceBucketData* bucket_data = &sample_buckets_[i];
580 bucket_data->callback.Run(bucket_data); 649 bucket_data->callback.Run(bucket_data);
581 } 650 }
582 } 651 }
583 652
584 void TraceSamplingThread::RegisterSampleBucket( 653 void TraceSamplingThread::RegisterSampleBucket(
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1007 &(json_events_str_ptr->data())); 1076 &(json_events_str_ptr->data()));
1008 1077
1009 if (!previous_logged_events->HasMoreEvents()) 1078 if (!previous_logged_events->HasMoreEvents())
1010 break; 1079 break;
1011 } 1080 }
1012 1081
1013 cb.Run(json_events_str_ptr); 1082 cb.Run(json_events_str_ptr);
1014 } 1083 }
1015 } 1084 }
1016 1085
1017 void TraceLog::AddTraceEvent(char phase, 1086 void TraceLog::AddTraceEvent(
1018 const unsigned char* category_enabled, 1087 char phase,
1019 const char* name, 1088 const unsigned char* category_enabled,
1020 unsigned long long id, 1089 const char* name,
1021 int num_args, 1090 unsigned long long id,
1022 const char** arg_names, 1091 int num_args,
1023 const unsigned char* arg_types, 1092 const char** arg_names,
1024 const unsigned long long* arg_values, 1093 const unsigned char* arg_types,
1025 unsigned char flags) { 1094 const unsigned long long* arg_values,
1095 scoped_ptr<ConvertableToJSON> convertable_values[],
1096 unsigned char flags) {
1026 int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 1097 int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1027 base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime(); 1098 base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
1028 AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id, 1099 AddTraceEventWithThreadIdAndTimestamp(phase, category_enabled, name, id,
1029 thread_id, now, num_args, arg_names, 1100 thread_id, now, num_args, arg_names,
1030 arg_types, arg_values, flags); 1101 arg_types, arg_values,
1102 convertable_values, flags);
1031 } 1103 }
1032 1104
1033 void TraceLog::AddTraceEventWithThreadIdAndTimestamp( 1105 void TraceLog::AddTraceEventWithThreadIdAndTimestamp(
1034 char phase, 1106 char phase,
1035 const unsigned char* category_enabled, 1107 const unsigned char* category_enabled,
1036 const char* name, 1108 const char* name,
1037 unsigned long long id, 1109 unsigned long long id,
1038 int thread_id, 1110 int thread_id,
1039 const TimeTicks& timestamp, 1111 const TimeTicks& timestamp,
1040 int num_args, 1112 int num_args,
1041 const char** arg_names, 1113 const char** arg_names,
1042 const unsigned char* arg_types, 1114 const unsigned char* arg_types,
1043 const unsigned long long* arg_values, 1115 const unsigned long long* arg_values,
1116 scoped_ptr<ConvertableToJSON> convertable_values[],
1044 unsigned char flags) { 1117 unsigned char flags) {
1045 DCHECK(name); 1118 DCHECK(name);
1046 1119
1047 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) 1120 if (flags & TRACE_EVENT_FLAG_MANGLE_ID)
1048 id ^= process_id_hash_; 1121 id ^= process_id_hash_;
1049 1122
1050 #if defined(OS_ANDROID) 1123 #if defined(OS_ANDROID)
1051 SendToATrace(phase, GetCategoryName(category_enabled), name, id, 1124 SendToATrace(phase, GetCategoryName(category_enabled), name, id,
1052 num_args, arg_names, arg_types, arg_values, flags); 1125 num_args, arg_names, arg_types, arg_values, flags);
1053 #endif 1126 #endif
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1090 if (!found) { 1163 if (!found) {
1091 existing_name->second.push_back(','); 1164 existing_name->second.push_back(',');
1092 existing_name->second.append(new_name); 1165 existing_name->second.append(new_name);
1093 } 1166 }
1094 } 1167 }
1095 } 1168 }
1096 1169
1097 logged_events_->AddEvent(TraceEvent(thread_id, 1170 logged_events_->AddEvent(TraceEvent(thread_id,
1098 now, phase, category_enabled, name, id, 1171 now, phase, category_enabled, name, id,
1099 num_args, arg_names, arg_types, arg_values, 1172 num_args, arg_names, arg_types, arg_values,
1100 flags)); 1173 convertable_values, flags));
1101 1174
1102 if (logged_events_->IsFull()) 1175 if (logged_events_->IsFull())
1103 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); 1176 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL);
1104 1177
1105 if (watch_category_ == category_enabled && watch_event_name_ == name) 1178 if (watch_category_ == category_enabled && watch_event_name_ == name)
1106 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); 1179 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION);
1107 1180
1108 event_callback_copy = event_callback_; 1181 event_callback_copy = event_callback_;
1109 } // release lock 1182 } // release lock
1110 1183
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 void TraceLog::AddThreadNameMetadataEvents() { 1245 void TraceLog::AddThreadNameMetadataEvents() {
1173 lock_.AssertAcquired(); 1246 lock_.AssertAcquired();
1174 for(hash_map<int, std::string>::iterator it = thread_names_.begin(); 1247 for(hash_map<int, std::string>::iterator it = thread_names_.begin();
1175 it != thread_names_.end(); 1248 it != thread_names_.end();
1176 it++) { 1249 it++) {
1177 if (!it->second.empty()) { 1250 if (!it->second.empty()) {
1178 int num_args = 1; 1251 int num_args = 1;
1179 const char* arg_name = "name"; 1252 const char* arg_name = "name";
1180 unsigned char arg_type; 1253 unsigned char arg_type;
1181 unsigned long long arg_value; 1254 unsigned long long arg_value;
1182 trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value); 1255 trace_event_internal::SetTraceValue(it->second, &arg_type, &arg_value,
1256 NULL);
1183 logged_events_->AddEvent(TraceEvent(it->first, 1257 logged_events_->AddEvent(TraceEvent(it->first,
1184 TimeTicks(), TRACE_EVENT_PHASE_METADATA, 1258 TimeTicks(), TRACE_EVENT_PHASE_METADATA,
1185 &g_category_enabled[g_category_metadata], 1259 &g_category_enabled[g_category_metadata],
1186 "thread_name", trace_event_internal::kNoEventId, 1260 "thread_name", trace_event_internal::kNoEventId,
1187 num_args, &arg_name, &arg_type, &arg_value, 1261 num_args, &arg_name, &arg_type, &arg_value, NULL,
1188 TRACE_EVENT_FLAG_NONE)); 1262 TRACE_EVENT_FLAG_NONE));
1189 } 1263 }
1190 } 1264 }
1191 } 1265 }
1192 1266
1193 void TraceLog::InstallWaitableEventForSamplingTesting( 1267 void TraceLog::InstallWaitableEventForSamplingTesting(
1194 WaitableEvent* waitable_event) { 1268 WaitableEvent* waitable_event) {
1195 sampling_thread_->InstallWaitableEventForSamplingTesting(waitable_event); 1269 sampling_thread_->InstallWaitableEventForSamplingTesting(waitable_event);
1196 } 1270 }
1197 1271
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 name_ = name; 1311 name_ = name;
1238 TRACE_EVENT_API_ADD_TRACE_EVENT( 1312 TRACE_EVENT_API_ADD_TRACE_EVENT(
1239 TRACE_EVENT_PHASE_BEGIN, // phase 1313 TRACE_EVENT_PHASE_BEGIN, // phase
1240 category_enabled_, // category enabled 1314 category_enabled_, // category enabled
1241 name, // name 1315 name, // name
1242 0, // id 1316 0, // id
1243 0, // num_args 1317 0, // num_args
1244 NULL, // arg_names 1318 NULL, // arg_names
1245 NULL, // arg_types 1319 NULL, // arg_types
1246 NULL, // arg_values 1320 NULL, // arg_values
1321 NULL, // convertable_values
1247 TRACE_EVENT_FLAG_NONE); // flags 1322 TRACE_EVENT_FLAG_NONE); // flags
1248 } else { 1323 } else {
1249 category_enabled_ = NULL; 1324 category_enabled_ = NULL;
1250 } 1325 }
1251 } 1326 }
1252 1327
1253 ScopedTrace::~ScopedTrace() { 1328 ScopedTrace::~ScopedTrace() {
1254 if (category_enabled_ && *category_enabled_) { 1329 if (category_enabled_ && *category_enabled_) {
1255 TRACE_EVENT_API_ADD_TRACE_EVENT( 1330 TRACE_EVENT_API_ADD_TRACE_EVENT(
1256 TRACE_EVENT_PHASE_END, // phase 1331 TRACE_EVENT_PHASE_END, // phase
1257 category_enabled_, // category enabled 1332 category_enabled_, // category enabled
1258 name_, // name 1333 name_, // name
1259 0, // id 1334 0, // id
1260 0, // num_args 1335 0, // num_args
1261 NULL, // arg_names 1336 NULL, // arg_names
1262 NULL, // arg_types 1337 NULL, // arg_types
1263 NULL, // arg_values 1338 NULL, // arg_values
1339 NULL, // convertable values
1264 TRACE_EVENT_FLAG_NONE); // flags 1340 TRACE_EVENT_FLAG_NONE); // flags
1265 } 1341 }
1266 } 1342 }
1267 1343
1268 } // namespace trace_event_internal 1344 } // namespace trace_event_internal
1269 1345
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698