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 |