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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
60 #define MAX_CATEGORY_GROUPS 100 | 62 #define MAX_CATEGORY_GROUPS 100 |
61 | 63 |
62 namespace { | 64 namespace { |
63 | 65 |
64 // Parallel arrays g_category_groups and g_category_group_enabled are separate | 66 // Parallel arrays g_category_groups and g_category_group_enabled are separate |
65 // so that a pointer to a member of g_category_group_enabled can be easily | 67 // so that a pointer to a member of g_category_group_enabled can be easily |
66 // converted to an index into g_category_groups. This allows macros to deal | 68 // converted to an index into g_category_groups. This allows macros to deal |
67 // only with char enabled pointers from g_category_group_enabled, and we can | 69 // only with char enabled pointers from g_category_group_enabled, and we can |
68 // convert internally to determine the category name from the char enabled | 70 // convert internally to determine the category name from the char enabled |
69 // pointer. | 71 // pointer. |
70 const char* g_category_groups[MAX_CATEGORY_GROUPS] = { | 72 const char* g_category_groups[MAX_CATEGORY_GROUPS] = { |
willchan no longer on Chromium
2013/07/03 17:55:19
Just noticed, we ought to make this const char* co
| |
71 "tracing already shutdown", | 73 "tracing already shutdown", |
72 "tracing categories exhausted; must increase MAX_CATEGORY_GROUPS", | 74 "tracing categories exhausted; must increase MAX_CATEGORY_GROUPS", |
73 "__metadata", | 75 "__metadata", |
74 }; | 76 }; |
75 | 77 |
76 // The enabled flag is char instead of bool so that the API can be used from C. | 78 // The enabled flag is char instead of bool so that the API can be used from C. |
77 unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = { 0 }; | 79 unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = { 0 }; |
78 const int g_category_already_shutdown = 0; | 80 const int g_category_already_shutdown = 0; |
79 const int g_category_categories_exhausted = 1; | 81 const int g_category_categories_exhausted = 1; |
80 const int g_category_metadata = 2; | 82 const int g_category_metadata = 2; |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
794 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], | 796 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], |
795 "trace_event category enabled"); | 797 "trace_event category enabled"); |
796 } | 798 } |
797 #if defined(OS_NACL) // NaCl shouldn't expose the process id. | 799 #if defined(OS_NACL) // NaCl shouldn't expose the process id. |
798 SetProcessID(0); | 800 SetProcessID(0); |
799 #else | 801 #else |
800 SetProcessID(static_cast<int>(GetCurrentProcId())); | 802 SetProcessID(static_cast<int>(GetCurrentProcId())); |
801 #endif | 803 #endif |
802 | 804 |
803 logged_events_.reset(GetTraceBuffer()); | 805 logged_events_.reset(GetTraceBuffer()); |
806 | |
807 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kTraceToConsole)) { | |
willchan no longer on Chromium
2013/07/03 17:55:19
Not super fond of this, but since nduca is fine wi
| |
808 std::string category_string = | |
809 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
810 switches::kTraceToConsole); | |
811 | |
812 if (!category_string.size()) | |
willchan no longer on Chromium
2013/07/03 17:55:19
STL doesn't specify the algorithmic complexity of
Ian Vollick
2013/07/03 18:48:03
Switched to empty().
| |
813 category_string = "*"; | |
814 | |
815 SetEnabled(CategoryFilter(category_string), ECHO_TO_CONSOLE); | |
816 } | |
804 } | 817 } |
805 | 818 |
806 TraceLog::~TraceLog() { | 819 TraceLog::~TraceLog() { |
807 } | 820 } |
808 | 821 |
809 const unsigned char* TraceLog::GetCategoryGroupEnabled( | 822 const unsigned char* TraceLog::GetCategoryGroupEnabled( |
810 const char* category_group) { | 823 const char* category_group) { |
811 TraceLog* tracelog = GetInstance(); | 824 TraceLog* tracelog = GetInstance(); |
812 if (!tracelog) { | 825 if (!tracelog) { |
813 DCHECK(!g_category_group_enabled[g_category_already_shutdown]); | 826 DCHECK(!g_category_group_enabled[g_category_already_shutdown]); |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1057 | 1070 |
1058 void TraceLog::SetNotificationCallback( | 1071 void TraceLog::SetNotificationCallback( |
1059 const TraceLog::NotificationCallback& cb) { | 1072 const TraceLog::NotificationCallback& cb) { |
1060 AutoLock lock(lock_); | 1073 AutoLock lock(lock_); |
1061 notification_callback_ = cb; | 1074 notification_callback_ = cb; |
1062 } | 1075 } |
1063 | 1076 |
1064 TraceBuffer* TraceLog::GetTraceBuffer() { | 1077 TraceBuffer* TraceLog::GetTraceBuffer() { |
1065 if (trace_options_ & RECORD_CONTINUOUSLY) | 1078 if (trace_options_ & RECORD_CONTINUOUSLY) |
1066 return new TraceBufferRingBuffer(); | 1079 return new TraceBufferRingBuffer(); |
1067 else if (trace_options_ & ECHO_TO_VLOG) | 1080 else if (trace_options_ & ECHO_TO_CONSOLE) |
1068 return new TraceBufferDiscardsEvents(); | 1081 return new TraceBufferDiscardsEvents(); |
1069 return new TraceBufferVector(); | 1082 return new TraceBufferVector(); |
1070 } | 1083 } |
1071 | 1084 |
1072 void TraceLog::SetEventCallback(EventCallback cb) { | 1085 void TraceLog::SetEventCallback(EventCallback cb) { |
1073 AutoLock lock(lock_); | 1086 AutoLock lock(lock_); |
1074 event_callback_ = cb; | 1087 event_callback_ = cb; |
1075 }; | 1088 }; |
1076 | 1089 |
1077 void TraceLog::Flush(const TraceLog::OutputCallback& cb) { | 1090 void TraceLog::Flush(const TraceLog::OutputCallback& cb) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1129 const TimeTicks& timestamp, | 1142 const TimeTicks& timestamp, |
1130 int num_args, | 1143 int num_args, |
1131 const char** arg_names, | 1144 const char** arg_names, |
1132 const unsigned char* arg_types, | 1145 const unsigned char* arg_types, |
1133 const unsigned long long* arg_values, | 1146 const unsigned long long* arg_values, |
1134 scoped_ptr<ConvertableToTraceFormat> convertable_values[], | 1147 scoped_ptr<ConvertableToTraceFormat> convertable_values[], |
1135 unsigned char flags) { | 1148 unsigned char flags) { |
1136 DCHECK(name); | 1149 DCHECK(name); |
1137 | 1150 |
1138 TimeDelta duration; | 1151 TimeDelta duration; |
1139 if (phase == TRACE_EVENT_PHASE_END && trace_options_ & ECHO_TO_VLOG) { | 1152 if (phase == TRACE_EVENT_PHASE_END && trace_options_ & ECHO_TO_CONSOLE) { |
1140 duration = timestamp - thread_event_start_times_[thread_id].top(); | 1153 duration = timestamp - thread_event_start_times_[thread_id].top(); |
1141 thread_event_start_times_[thread_id].pop(); | 1154 thread_event_start_times_[thread_id].pop(); |
1142 } | 1155 } |
1143 | 1156 |
1144 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) | 1157 if (flags & TRACE_EVENT_FLAG_MANGLE_ID) |
1145 id ^= process_id_hash_; | 1158 id ^= process_id_hash_; |
1146 | 1159 |
1147 #if defined(OS_ANDROID) | 1160 #if defined(OS_ANDROID) |
1148 SendToATrace(phase, GetCategoryGroupName(category_group_enabled), name, id, | 1161 SendToATrace(phase, GetCategoryGroupName(category_group_enabled), name, id, |
1149 num_args, arg_names, arg_types, arg_values, convertable_values, | 1162 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(), | 1200 bool found = std::find(existing_names.begin(), |
1188 existing_names.end(), | 1201 existing_names.end(), |
1189 new_name) != existing_names.end(); | 1202 new_name) != existing_names.end(); |
1190 if (!found) { | 1203 if (!found) { |
1191 existing_name->second.push_back(','); | 1204 existing_name->second.push_back(','); |
1192 existing_name->second.append(new_name); | 1205 existing_name->second.append(new_name); |
1193 } | 1206 } |
1194 } | 1207 } |
1195 } | 1208 } |
1196 | 1209 |
1197 if (trace_options_ & ECHO_TO_VLOG) { | 1210 if (trace_options_ & ECHO_TO_CONSOLE) { |
1198 std::string thread_name = thread_names_[thread_id]; | 1211 std::string thread_name = thread_names_[thread_id]; |
1199 if (thread_colors_.find(thread_name) == thread_colors_.end()) | 1212 if (thread_colors_.find(thread_name) == thread_colors_.end()) |
1200 thread_colors_[thread_name] = (thread_colors_.size() % 6) + 1; | 1213 thread_colors_[thread_name] = (thread_colors_.size() % 6) + 1; |
1201 | 1214 |
1202 std::ostringstream log; | 1215 std::ostringstream log; |
1203 log << base::StringPrintf("%s: \x1b[0;3%dm", | 1216 log << base::StringPrintf("%s: \x1b[0;3%dm", |
1204 thread_name.c_str(), | 1217 thread_name.c_str(), |
1205 thread_colors_[thread_name]); | 1218 thread_colors_[thread_name]); |
1206 | 1219 |
1207 size_t depth = 0; | 1220 size_t depth = 0; |
1208 if (thread_event_start_times_.find(thread_id) != | 1221 if (thread_event_start_times_.find(thread_id) != |
1209 thread_event_start_times_.end()) | 1222 thread_event_start_times_.end()) |
1210 depth = thread_event_start_times_[thread_id].size(); | 1223 depth = thread_event_start_times_[thread_id].size(); |
1211 | 1224 |
1212 for (size_t i = 0; i < depth; ++i) | 1225 for (size_t i = 0; i < depth; ++i) |
1213 log << "| "; | 1226 log << "| "; |
1214 | 1227 |
1215 log << base::StringPrintf("'%c', %s", phase, name); | 1228 log << base::StringPrintf("'%c', %s", phase, name); |
1216 | 1229 |
1217 if (phase == TRACE_EVENT_PHASE_END) | 1230 if (phase == TRACE_EVENT_PHASE_END) |
1218 log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF()); | 1231 log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF()); |
1219 | 1232 |
1220 VLOG(0) << log.str() << "\x1b[0;m"; | 1233 LOG(ERROR) << log.str() << "\x1b[0;m"; |
1221 } | 1234 } |
1222 | 1235 |
1223 logged_events_->AddEvent(TraceEvent(thread_id, | 1236 logged_events_->AddEvent(TraceEvent(thread_id, |
1224 now, phase, category_group_enabled, name, id, | 1237 now, phase, category_group_enabled, name, id, |
1225 num_args, arg_names, arg_types, arg_values, | 1238 num_args, arg_names, arg_types, arg_values, |
1226 convertable_values, flags)); | 1239 convertable_values, flags)); |
1227 | 1240 |
1228 if (logged_events_->IsFull()) | 1241 if (logged_events_->IsFull()) |
1229 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); | 1242 notifier.AddNotificationWhileLocked(TRACE_BUFFER_FULL); |
1230 | 1243 |
1231 if (watch_category_ == category_group_enabled && watch_event_name_ == name) | 1244 if (watch_category_ == category_group_enabled && watch_event_name_ == name) |
1232 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); | 1245 notifier.AddNotificationWhileLocked(EVENT_WATCH_NOTIFICATION); |
1233 } while (0); // release lock | 1246 } while (0); // release lock |
1234 | 1247 |
1235 if (phase == TRACE_EVENT_PHASE_BEGIN && trace_options_ & ECHO_TO_VLOG) | 1248 if (phase == TRACE_EVENT_PHASE_BEGIN && trace_options_ & ECHO_TO_CONSOLE) |
1236 thread_event_start_times_[thread_id].push(timestamp); | 1249 thread_event_start_times_[thread_id].push(timestamp); |
1237 | 1250 |
1238 notifier.SendNotificationIfAny(); | 1251 notifier.SendNotificationIfAny(); |
1239 if (event_callback_copy != NULL) { | 1252 if (event_callback_copy != NULL) { |
1240 event_callback_copy(phase, category_group_enabled, name, id, | 1253 event_callback_copy(phase, category_group_enabled, name, id, |
1241 num_args, arg_names, arg_types, arg_values, | 1254 num_args, arg_names, arg_types, arg_values, |
1242 flags); | 1255 flags); |
1243 } | 1256 } |
1244 } | 1257 } |
1245 | 1258 |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1549 0, // num_args | 1562 0, // num_args |
1550 NULL, // arg_names | 1563 NULL, // arg_names |
1551 NULL, // arg_types | 1564 NULL, // arg_types |
1552 NULL, // arg_values | 1565 NULL, // arg_values |
1553 NULL, // convertable values | 1566 NULL, // convertable values |
1554 TRACE_EVENT_FLAG_NONE); // flags | 1567 TRACE_EVENT_FLAG_NONE); // flags |
1555 } | 1568 } |
1556 } | 1569 } |
1557 | 1570 |
1558 } // namespace trace_event_internal | 1571 } // namespace trace_event_internal |
OLD | NEW |