| 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/base_switches.h" |
| 9 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/command_line.h" |
| 10 #include "base/debug/leak_annotations.h" | 12 #include "base/debug/leak_annotations.h" |
| 11 #include "base/debug/trace_event.h" | 13 #include "base/debug/trace_event.h" |
| 12 #include "base/format_macros.h" | 14 #include "base/format_macros.h" |
| 13 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
| 14 #include "base/memory/singleton.h" | 16 #include "base/memory/singleton.h" |
| 15 #include "base/process_util.h" | 17 #include "base/process_util.h" |
| 16 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
| 17 #include "base/strings/string_split.h" | 19 #include "base/strings/string_split.h" |
| 18 #include "base/strings/string_tokenizer.h" | 20 #include "base/strings/string_tokenizer.h" |
| 19 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 case TRACE_EVENT_SCOPE_THREAD: | 530 case TRACE_EVENT_SCOPE_THREAD: |
| 529 scope = TRACE_EVENT_SCOPE_NAME_THREAD; | 531 scope = TRACE_EVENT_SCOPE_NAME_THREAD; |
| 530 break; | 532 break; |
| 531 } | 533 } |
| 532 StringAppendF(out, ",\"s\":\"%c\"", scope); | 534 StringAppendF(out, ",\"s\":\"%c\"", scope); |
| 533 } | 535 } |
| 534 | 536 |
| 535 *out += "}"; | 537 *out += "}"; |
| 536 } | 538 } |
| 537 | 539 |
| 540 void TraceEvent::AppendPrettyPrinted(std::ostringstream* out) const { |
| 541 *out << name_ << "["; |
| 542 *out << TraceLog::GetCategoryGroupName(category_group_enabled_); |
| 543 *out << "]"; |
| 544 if (arg_names_[0]) { |
| 545 *out << ", {"; |
| 546 for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) { |
| 547 if (i > 0) |
| 548 *out << ", "; |
| 549 *out << arg_names_[i] << ":"; |
| 550 std::string value_as_text; |
| 551 |
| 552 if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) |
| 553 convertable_values_[i]->AppendAsTraceFormat(&value_as_text); |
| 554 else |
| 555 AppendValueAsJSON(arg_types_[i], arg_values_[i], &value_as_text); |
| 556 |
| 557 *out << value_as_text; |
| 558 } |
| 559 *out << "}"; |
| 560 } |
| 561 } |
| 562 |
| 538 //////////////////////////////////////////////////////////////////////////////// | 563 //////////////////////////////////////////////////////////////////////////////// |
| 539 // | 564 // |
| 540 // TraceResultBuffer | 565 // TraceResultBuffer |
| 541 // | 566 // |
| 542 //////////////////////////////////////////////////////////////////////////////// | 567 //////////////////////////////////////////////////////////////////////////////// |
| 543 | 568 |
| 544 TraceResultBuffer::OutputCallback | 569 TraceResultBuffer::OutputCallback |
| 545 TraceResultBuffer::SimpleOutput::GetCallback() { | 570 TraceResultBuffer::SimpleOutput::GetCallback() { |
| 546 return Bind(&SimpleOutput::Append, Unretained(this)); | 571 return Bind(&SimpleOutput::Append, Unretained(this)); |
| 547 } | 572 } |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 // sizeof(g_category_group_enabled), | 816 // sizeof(g_category_group_enabled), |
| 792 // "trace_event category enabled"); | 817 // "trace_event category enabled"); |
| 793 for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) { | 818 for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) { |
| 794 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], | 819 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], |
| 795 "trace_event category enabled"); | 820 "trace_event category enabled"); |
| 796 } | 821 } |
| 797 #if defined(OS_NACL) // NaCl shouldn't expose the process id. | 822 #if defined(OS_NACL) // NaCl shouldn't expose the process id. |
| 798 SetProcessID(0); | 823 SetProcessID(0); |
| 799 #else | 824 #else |
| 800 SetProcessID(static_cast<int>(GetCurrentProcId())); | 825 SetProcessID(static_cast<int>(GetCurrentProcId())); |
| 826 |
| 827 // NaCl also shouldn't access the command line. |
| 828 if (CommandLine::InitializedForCurrentProcess() && |
| 829 CommandLine::ForCurrentProcess()->HasSwitch(switches::kTraceToConsole)) { |
| 830 std::string category_string = |
| 831 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 832 switches::kTraceToConsole); |
| 833 |
| 834 if (category_string.empty()) |
| 835 category_string = "*"; |
| 836 |
| 837 SetEnabled(CategoryFilter(category_string), ECHO_TO_CONSOLE); |
| 838 } |
| 801 #endif | 839 #endif |
| 802 | 840 |
| 803 logged_events_.reset(GetTraceBuffer()); | 841 logged_events_.reset(GetTraceBuffer()); |
| 804 } | 842 } |
| 805 | 843 |
| 806 TraceLog::~TraceLog() { | 844 TraceLog::~TraceLog() { |
| 807 } | 845 } |
| 808 | 846 |
| 809 const unsigned char* TraceLog::GetCategoryGroupEnabled( | 847 const unsigned char* TraceLog::GetCategoryGroupEnabled( |
| 810 const char* category_group) { | 848 const char* category_group) { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 | 1095 |
| 1058 void TraceLog::SetNotificationCallback( | 1096 void TraceLog::SetNotificationCallback( |
| 1059 const TraceLog::NotificationCallback& cb) { | 1097 const TraceLog::NotificationCallback& cb) { |
| 1060 AutoLock lock(lock_); | 1098 AutoLock lock(lock_); |
| 1061 notification_callback_ = cb; | 1099 notification_callback_ = cb; |
| 1062 } | 1100 } |
| 1063 | 1101 |
| 1064 TraceBuffer* TraceLog::GetTraceBuffer() { | 1102 TraceBuffer* TraceLog::GetTraceBuffer() { |
| 1065 if (trace_options_ & RECORD_CONTINUOUSLY) | 1103 if (trace_options_ & RECORD_CONTINUOUSLY) |
| 1066 return new TraceBufferRingBuffer(); | 1104 return new TraceBufferRingBuffer(); |
| 1067 else if (trace_options_ & ECHO_TO_VLOG) | 1105 else if (trace_options_ & ECHO_TO_CONSOLE) |
| 1068 return new TraceBufferDiscardsEvents(); | 1106 return new TraceBufferDiscardsEvents(); |
| 1069 return new TraceBufferVector(); | 1107 return new TraceBufferVector(); |
| 1070 } | 1108 } |
| 1071 | 1109 |
| 1072 void TraceLog::SetEventCallback(EventCallback cb) { | 1110 void TraceLog::SetEventCallback(EventCallback cb) { |
| 1073 AutoLock lock(lock_); | 1111 AutoLock lock(lock_); |
| 1074 event_callback_ = cb; | 1112 event_callback_ = cb; |
| 1075 }; | 1113 }; |
| 1076 | 1114 |
| 1077 void TraceLog::Flush(const TraceLog::OutputCallback& cb) { | 1115 void TraceLog::Flush(const TraceLog::OutputCallback& cb) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 const TimeTicks& timestamp, | 1167 const TimeTicks& timestamp, |
| 1130 int num_args, | 1168 int num_args, |
| 1131 const char** arg_names, | 1169 const char** arg_names, |
| 1132 const unsigned char* arg_types, | 1170 const unsigned char* arg_types, |
| 1133 const unsigned long long* arg_values, | 1171 const unsigned long long* arg_values, |
| 1134 scoped_ptr<ConvertableToTraceFormat> convertable_values[], | 1172 scoped_ptr<ConvertableToTraceFormat> convertable_values[], |
| 1135 unsigned char flags) { | 1173 unsigned char flags) { |
| 1136 DCHECK(name); | 1174 DCHECK(name); |
| 1137 | 1175 |
| 1138 TimeDelta duration; | 1176 TimeDelta duration; |
| 1139 if (phase == TRACE_EVENT_PHASE_END && trace_options_ & ECHO_TO_VLOG) { | 1177 if (phase == TRACE_EVENT_PHASE_END && trace_options_ & ECHO_TO_CONSOLE) { |
| 1140 duration = timestamp - thread_event_start_times_[thread_id].top(); | 1178 duration = timestamp - thread_event_start_times_[thread_id].top(); |
| 1141 thread_event_start_times_[thread_id].pop(); | 1179 thread_event_start_times_[thread_id].pop(); |
| 1142 } | 1180 } |
| 1143 | 1181 |
| 1144 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) | 1182 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) |
| 1145 id ^= process_id_hash_; | 1183 id ^= process_id_hash_; |
| 1146 | 1184 |
| 1147 #if defined(OS_ANDROID) | 1185 #if defined(OS_ANDROID) |
| 1148 SendToATrace(phase, GetCategoryGroupName(category_group_enabled), name, id, | 1186 SendToATrace(phase, GetCategoryGroupName(category_group_enabled), name, id, |
| 1149 num_args, arg_names, arg_types, arg_values, convertable_values, | 1187 num_args, arg_names, arg_types, arg_values, convertable_values, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1187 bool found = std::find(existing_names.begin(), | 1225 bool found = std::find(existing_names.begin(), |
| 1188 existing_names.end(), | 1226 existing_names.end(), |
| 1189 new_name) != existing_names.end(); | 1227 new_name) != existing_names.end(); |
| 1190 if (!found) { | 1228 if (!found) { |
| 1191 existing_name->second.push_back(','); | 1229 existing_name->second.push_back(','); |
| 1192 existing_name->second.append(new_name); | 1230 existing_name->second.append(new_name); |
| 1193 } | 1231 } |
| 1194 } | 1232 } |
| 1195 } | 1233 } |
| 1196 | 1234 |
| 1197 if (trace_options_ & ECHO_TO_VLOG) { | 1235 TraceEvent trace_event(thread_id, |
| 1236 now, phase, category_group_enabled, name, id, |
| 1237 num_args, arg_names, arg_types, arg_values, |
| 1238 convertable_values, flags); |
| 1239 |
| 1240 logged_events_->AddEvent(trace_event); |
| 1241 |
| 1242 if (trace_options_ & ECHO_TO_CONSOLE) { |
| 1198 std::string thread_name = thread_names_[thread_id]; | 1243 std::string thread_name = thread_names_[thread_id]; |
| 1199 if (thread_colors_.find(thread_name) == thread_colors_.end()) | 1244 if (thread_colors_.find(thread_name) == thread_colors_.end()) |
| 1200 thread_colors_[thread_name] = (thread_colors_.size() % 6) + 1; | 1245 thread_colors_[thread_name] = (thread_colors_.size() % 6) + 1; |
| 1201 | 1246 |
| 1202 std::ostringstream log; | 1247 std::ostringstream log; |
| 1203 log << base::StringPrintf("%s: \x1b[0;3%dm", | 1248 log << base::StringPrintf("%s: \x1b[0;3%dm", |
| 1204 thread_name.c_str(), | 1249 thread_name.c_str(), |
| 1205 thread_colors_[thread_name]); | 1250 thread_colors_[thread_name]); |
| 1206 | 1251 |
| 1207 size_t depth = 0; | 1252 size_t depth = 0; |
| 1208 if (thread_event_start_times_.find(thread_id) != | 1253 if (thread_event_start_times_.find(thread_id) != |
| 1209 thread_event_start_times_.end()) | 1254 thread_event_start_times_.end()) |
| 1210 depth = thread_event_start_times_[thread_id].size(); | 1255 depth = thread_event_start_times_[thread_id].size(); |
| 1211 | 1256 |
| 1212 for (size_t i = 0; i < depth; ++i) | 1257 for (size_t i = 0; i < depth; ++i) |
| 1213 log << "| "; | 1258 log << "| "; |
| 1214 | 1259 |
| 1215 log << base::StringPrintf("'%c', %s", phase, name); | 1260 trace_event.AppendPrettyPrinted(&log); |
| 1216 | |
| 1217 if (phase == TRACE_EVENT_PHASE_END) | 1261 if (phase == TRACE_EVENT_PHASE_END) |
| 1218 log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF()); | 1262 log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF()); |
| 1219 | 1263 |
| 1220 VLOG(0) << log.str() << "\x1b[0;m"; | 1264 LOG(ERROR) << log.str() << "\x1b[0;m"; |
| 1221 } | 1265 } |
| 1222 | 1266 |
| 1223 logged_events_->AddEvent(TraceEvent(thread_id, | |
| 1224 now, phase, category_group_enabled, name, id, | |
| 1225 num_args, arg_names, arg_types, arg_values, | |
| 1226 convertable_values, flags)); | |
| 1227 | |
| 1228 if (logged_events_->IsFull()) | 1267 if (logged_events_->IsFull()) |
| 1229 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); | 1268 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); |
| 1230 | 1269 |
| 1231 if (watch_category_ == category_group_enabled && watch_event_name_ == name) | 1270 if (watch_category_ == category_group_enabled && watch_event_name_ == name) |
| 1232 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); | 1271 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); |
| 1233 } while (0); // release lock | 1272 } while (0); // release lock |
| 1234 | 1273 |
| 1235 if (phase == TRACE_EVENT_PHASE_BEGIN && trace_options_ & ECHO_TO_VLOG) | 1274 if (phase == TRACE_EVENT_PHASE_BEGIN && trace_options_ & ECHO_TO_CONSOLE) |
| 1236 thread_event_start_times_[thread_id].push(timestamp); | 1275 thread_event_start_times_[thread_id].push(timestamp); |
| 1237 | 1276 |
| 1238 notifier.SendNotificationIfAny(); | 1277 notifier.SendNotificationIfAny(); |
| 1239 if (event_callback_copy != NULL) { | 1278 if (event_callback_copy != NULL) { |
| 1240 event_callback_copy(phase, category_group_enabled, name, id, | 1279 event_callback_copy(phase, category_group_enabled, name, id, |
| 1241 num_args, arg_names, arg_types, arg_values, | 1280 num_args, arg_names, arg_types, arg_values, |
| 1242 flags); | 1281 flags); |
| 1243 } | 1282 } |
| 1244 } | 1283 } |
| 1245 | 1284 |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1636 0, // num_args | 1675 0, // num_args |
| 1637 NULL, // arg_names | 1676 NULL, // arg_names |
| 1638 NULL, // arg_types | 1677 NULL, // arg_types |
| 1639 NULL, // arg_values | 1678 NULL, // arg_values |
| 1640 NULL, // convertable values | 1679 NULL, // convertable values |
| 1641 TRACE_EVENT_FLAG_NONE); // flags | 1680 TRACE_EVENT_FLAG_NONE); // flags |
| 1642 } | 1681 } |
| 1643 } | 1682 } |
| 1644 | 1683 |
| 1645 } // namespace trace_event_internal | 1684 } // namespace trace_event_internal |
| OLD | NEW |