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/base_switches.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1087 void TraceLog::ThreadLocalEventBuffer::WillDestroyCurrentMessageLoop() { | 1087 void TraceLog::ThreadLocalEventBuffer::WillDestroyCurrentMessageLoop() { |
1088 delete this; | 1088 delete this; |
1089 } | 1089 } |
1090 | 1090 |
1091 void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() { | 1091 void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() { |
1092 if (!chunk_) | 1092 if (!chunk_) |
1093 return; | 1093 return; |
1094 | 1094 |
1095 trace_log_->lock_.AssertAcquired(); | 1095 trace_log_->lock_.AssertAcquired(); |
1096 if (trace_log_->CheckGeneration(generation_)) { | 1096 if (trace_log_->CheckGeneration(generation_)) { |
1097 // Return the chunk to the buffer only if the generation matches, | 1097 // Return the chunk to the buffer only if the generation matches. |
1098 trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass()); | 1098 trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass()); |
1099 } | 1099 } |
1100 // Otherwise this method may be called from the destructor, or TraceLog will | 1100 // Otherwise this method may be called from the destructor, or TraceLog will |
1101 // find the generation mismatch and delete this buffer soon. | 1101 // find the generation mismatch and delete this buffer soon. |
1102 } | 1102 } |
1103 | 1103 |
1104 // static | 1104 // static |
1105 TraceLog* TraceLog::GetInstance() { | 1105 TraceLog* TraceLog::GetInstance() { |
1106 return Singleton<TraceLog, LeakySingletonTraits<TraceLog> >::get(); | 1106 return Singleton<TraceLog, LeakySingletonTraits<TraceLog> >::get(); |
1107 } | 1107 } |
1108 | 1108 |
1109 TraceLog::TraceLog() | 1109 TraceLog::TraceLog() |
1110 : enabled_(false), | 1110 : mode_(DISABLED), |
1111 num_traces_recorded_(0), | 1111 num_traces_recorded_(0), |
1112 event_callback_(0), | 1112 event_callback_(0), |
1113 dispatching_to_observer_list_(false), | 1113 dispatching_to_observer_list_(false), |
1114 process_sort_index_(0), | 1114 process_sort_index_(0), |
1115 process_id_hash_(0), | 1115 process_id_hash_(0), |
1116 process_id_(0), | 1116 process_id_(0), |
1117 watch_category_(0), | 1117 watch_category_(0), |
1118 trace_options_(RECORD_UNTIL_FULL), | 1118 trace_options_(RECORD_UNTIL_FULL), |
1119 sampling_thread_handle_(0), | 1119 sampling_thread_handle_(0), |
1120 category_filter_(CategoryFilter::kDefaultCategoryFilterString), | 1120 category_filter_(CategoryFilter::kDefaultCategoryFilterString), |
(...skipping 25 matching lines...) Expand all Loading... | |
1146 switches::kTraceToConsole); | 1146 switches::kTraceToConsole); |
1147 if (filter.empty()) { | 1147 if (filter.empty()) { |
1148 filter = kEchoToConsoleCategoryFilter; | 1148 filter = kEchoToConsoleCategoryFilter; |
1149 } else { | 1149 } else { |
1150 filter.append(","); | 1150 filter.append(","); |
1151 filter.append(kEchoToConsoleCategoryFilter); | 1151 filter.append(kEchoToConsoleCategoryFilter); |
1152 } | 1152 } |
1153 | 1153 |
1154 LOG(ERROR) << "Start " << switches::kTraceToConsole | 1154 LOG(ERROR) << "Start " << switches::kTraceToConsole |
1155 << " with CategoryFilter '" << filter << "'."; | 1155 << " with CategoryFilter '" << filter << "'."; |
1156 SetEnabled(CategoryFilter(filter), ECHO_TO_CONSOLE); | 1156 SetEnabled(CategoryFilter(filter), RECORDING_MODE, ECHO_TO_CONSOLE); |
1157 } | 1157 } |
1158 #endif | 1158 #endif |
1159 | 1159 |
1160 logged_events_.reset(CreateTraceBuffer()); | 1160 logged_events_.reset(CreateTraceBuffer()); |
1161 } | 1161 } |
1162 | 1162 |
1163 TraceLog::~TraceLog() { | 1163 TraceLog::~TraceLog() { |
1164 } | 1164 } |
1165 | 1165 |
1166 const unsigned char* TraceLog::GetCategoryGroupEnabled( | 1166 const unsigned char* TraceLog::GetCategoryGroupEnabled( |
(...skipping 18 matching lines...) Expand all Loading... | |
1185 g_category_group_enabled + MAX_CATEGORY_GROUPS)) << | 1185 g_category_group_enabled + MAX_CATEGORY_GROUPS)) << |
1186 "out of bounds category pointer"; | 1186 "out of bounds category pointer"; |
1187 uintptr_t category_index = | 1187 uintptr_t category_index = |
1188 (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]); | 1188 (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]); |
1189 return g_category_groups[category_index]; | 1189 return g_category_groups[category_index]; |
1190 } | 1190 } |
1191 | 1191 |
1192 void TraceLog::UpdateCategoryGroupEnabledFlag(int category_index) { | 1192 void TraceLog::UpdateCategoryGroupEnabledFlag(int category_index) { |
1193 unsigned char enabled_flag = 0; | 1193 unsigned char enabled_flag = 0; |
1194 const char* category_group = g_category_groups[category_index]; | 1194 const char* category_group = g_category_groups[category_index]; |
1195 if (enabled_ && category_filter_.IsCategoryGroupEnabled(category_group)) | 1195 if (mode_ == RECORDING_MODE && |
1196 category_filter_.IsCategoryGroupEnabled(category_group)) | |
1196 enabled_flag |= ENABLED_FOR_RECORDING; | 1197 enabled_flag |= ENABLED_FOR_RECORDING; |
1198 if (mode_ == MONITORING_MODE && | |
dsinclair
2013/12/20 14:42:29
else if?
haraken
2013/12/25 07:52:31
Done.
| |
1199 category_filter_.IsCategoryGroupEnabled(category_group)) | |
1200 enabled_flag |= ENABLED_FOR_MONITORING; | |
1197 if (event_callback_ && | 1201 if (event_callback_ && |
1198 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) | 1202 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) |
1199 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; | 1203 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; |
1200 g_category_group_enabled[category_index] = enabled_flag; | 1204 g_category_group_enabled[category_index] = enabled_flag; |
1201 } | 1205 } |
1202 | 1206 |
1203 void TraceLog::UpdateCategoryGroupEnabledFlags() { | 1207 void TraceLog::UpdateCategoryGroupEnabledFlags() { |
1204 for (int i = 0; i < g_category_index; i++) | 1208 for (int i = 0; i < g_category_index; i++) |
1205 UpdateCategoryGroupEnabledFlag(i); | 1209 UpdateCategoryGroupEnabledFlag(i); |
1206 } | 1210 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1249 void TraceLog::GetKnownCategoryGroups( | 1253 void TraceLog::GetKnownCategoryGroups( |
1250 std::vector<std::string>* category_groups) { | 1254 std::vector<std::string>* category_groups) { |
1251 AutoLock lock(lock_); | 1255 AutoLock lock(lock_); |
1252 category_groups->push_back( | 1256 category_groups->push_back( |
1253 g_category_groups[g_category_trace_event_overhead]); | 1257 g_category_groups[g_category_trace_event_overhead]); |
1254 for (int i = g_num_builtin_categories; i < g_category_index; i++) | 1258 for (int i = g_num_builtin_categories; i < g_category_index; i++) |
1255 category_groups->push_back(g_category_groups[i]); | 1259 category_groups->push_back(g_category_groups[i]); |
1256 } | 1260 } |
1257 | 1261 |
1258 void TraceLog::SetEnabled(const CategoryFilter& category_filter, | 1262 void TraceLog::SetEnabled(const CategoryFilter& category_filter, |
1263 Mode mode, | |
1259 Options options) { | 1264 Options options) { |
1260 std::vector<EnabledStateObserver*> observer_list; | 1265 std::vector<EnabledStateObserver*> observer_list; |
1261 { | 1266 { |
1262 AutoLock lock(lock_); | 1267 AutoLock lock(lock_); |
1263 | 1268 |
1264 // Can't enable tracing when Flush() is in progress. | 1269 // Can't enable tracing when Flush() is in progress. |
1265 DCHECK(!flush_message_loop_proxy_.get()); | 1270 DCHECK(!flush_message_loop_proxy_.get()); |
1266 | 1271 |
1267 Options old_options = trace_options(); | 1272 Options old_options = trace_options(); |
1268 | 1273 |
1269 if (enabled_) { | 1274 if (IsEnabled()) { |
1270 if (options != old_options) { | 1275 if (options != old_options) { |
1271 DLOG(ERROR) << "Attemting to re-enable tracing with a different " | 1276 DLOG(ERROR) << "Attemting to re-enable tracing with a different " |
1272 << "set of options."; | 1277 << "set of options."; |
1273 } | 1278 } |
1274 | 1279 |
1280 if (mode != mode_) { | |
1281 DLOG(ERROR) << "Attemting to re-enable tracing with a different mode."; | |
1282 } | |
1283 | |
1275 category_filter_.Merge(category_filter); | 1284 category_filter_.Merge(category_filter); |
1276 UpdateCategoryGroupEnabledFlags(); | 1285 UpdateCategoryGroupEnabledFlags(); |
1277 return; | 1286 return; |
1278 } | 1287 } |
1279 | 1288 |
1280 if (dispatching_to_observer_list_) { | 1289 if (dispatching_to_observer_list_) { |
1281 DLOG(ERROR) << | 1290 DLOG(ERROR) << |
1282 "Cannot manipulate TraceLog::Enabled state from an observer."; | 1291 "Cannot manipulate TraceLog::Enabled state from an observer."; |
1283 return; | 1292 return; |
1284 } | 1293 } |
1285 | 1294 |
1286 enabled_ = true; | 1295 mode_ = mode; |
1287 | 1296 |
1288 if (options != old_options) { | 1297 if (options != old_options) { |
1289 subtle::NoBarrier_Store(&trace_options_, options); | 1298 subtle::NoBarrier_Store(&trace_options_, options); |
1290 UseNextTraceBuffer(); | 1299 UseNextTraceBuffer(); |
1291 } | 1300 } |
1292 | 1301 |
1293 num_traces_recorded_++; | 1302 num_traces_recorded_++; |
1294 | 1303 |
1295 category_filter_ = CategoryFilter(category_filter); | 1304 category_filter_ = CategoryFilter(category_filter); |
1296 UpdateCategoryGroupEnabledFlags(); | 1305 UpdateCategoryGroupEnabledFlags(); |
1297 | 1306 |
1298 if ((options & ENABLE_SAMPLING) || (options & MONITOR_SAMPLING)) { | 1307 if (options & ENABLE_SAMPLING) { |
1299 sampling_thread_.reset(new TraceSamplingThread); | 1308 sampling_thread_.reset(new TraceSamplingThread); |
1300 sampling_thread_->RegisterSampleBucket( | 1309 sampling_thread_->RegisterSampleBucket( |
1301 &g_trace_state[0], | 1310 &g_trace_state[0], |
1302 "bucket0", | 1311 "bucket0", |
1303 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | 1312 Bind(&TraceSamplingThread::DefaultSamplingCallback)); |
1304 sampling_thread_->RegisterSampleBucket( | 1313 sampling_thread_->RegisterSampleBucket( |
1305 &g_trace_state[1], | 1314 &g_trace_state[1], |
1306 "bucket1", | 1315 "bucket1", |
1307 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | 1316 Bind(&TraceSamplingThread::DefaultSamplingCallback)); |
1308 sampling_thread_->RegisterSampleBucket( | 1317 sampling_thread_->RegisterSampleBucket( |
(...skipping 25 matching lines...) Expand all Loading... | |
1334 } | 1343 } |
1335 | 1344 |
1336 void TraceLog::SetDisabled() { | 1345 void TraceLog::SetDisabled() { |
1337 AutoLock lock(lock_); | 1346 AutoLock lock(lock_); |
1338 SetDisabledWhileLocked(); | 1347 SetDisabledWhileLocked(); |
1339 } | 1348 } |
1340 | 1349 |
1341 void TraceLog::SetDisabledWhileLocked() { | 1350 void TraceLog::SetDisabledWhileLocked() { |
1342 lock_.AssertAcquired(); | 1351 lock_.AssertAcquired(); |
1343 | 1352 |
1344 if (!enabled_) | 1353 if (!IsEnabled()) |
1345 return; | 1354 return; |
1346 | 1355 |
1347 if (dispatching_to_observer_list_) { | 1356 if (dispatching_to_observer_list_) { |
1348 DLOG(ERROR) | 1357 DLOG(ERROR) |
1349 << "Cannot manipulate TraceLog::Enabled state from an observer."; | 1358 << "Cannot manipulate TraceLog::Enabled state from an observer."; |
1350 return; | 1359 return; |
1351 } | 1360 } |
1352 | 1361 |
1353 enabled_ = false; | 1362 mode_ = DISABLED; |
1354 | 1363 |
1355 if (sampling_thread_.get()) { | 1364 if (sampling_thread_.get()) { |
1356 // Stop the sampling thread. | 1365 // Stop the sampling thread. |
1357 sampling_thread_->Stop(); | 1366 sampling_thread_->Stop(); |
1358 lock_.Release(); | 1367 lock_.Release(); |
1359 PlatformThread::Join(sampling_thread_handle_); | 1368 PlatformThread::Join(sampling_thread_handle_); |
1360 lock_.Acquire(); | 1369 lock_.Acquire(); |
1361 sampling_thread_handle_ = PlatformThreadHandle(); | 1370 sampling_thread_handle_ = PlatformThreadHandle(); |
1362 sampling_thread_.reset(); | 1371 sampling_thread_.reset(); |
1363 } | 1372 } |
(...skipping 13 matching lines...) Expand all Loading... | |
1377 // trace event. | 1386 // trace event. |
1378 AutoUnlock unlock(lock_); | 1387 AutoUnlock unlock(lock_); |
1379 for (size_t i = 0; i < observer_list.size(); ++i) | 1388 for (size_t i = 0; i < observer_list.size(); ++i) |
1380 observer_list[i]->OnTraceLogDisabled(); | 1389 observer_list[i]->OnTraceLogDisabled(); |
1381 } | 1390 } |
1382 dispatching_to_observer_list_ = false; | 1391 dispatching_to_observer_list_ = false; |
1383 } | 1392 } |
1384 | 1393 |
1385 int TraceLog::GetNumTracesRecorded() { | 1394 int TraceLog::GetNumTracesRecorded() { |
1386 AutoLock lock(lock_); | 1395 AutoLock lock(lock_); |
1387 if (!enabled_) | 1396 if (!IsEnabled()) |
1388 return -1; | 1397 return -1; |
1389 return num_traces_recorded_; | 1398 return num_traces_recorded_; |
1390 } | 1399 } |
1391 | 1400 |
1392 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { | 1401 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { |
1393 enabled_state_observer_list_.push_back(listener); | 1402 enabled_state_observer_list_.push_back(listener); |
1394 } | 1403 } |
1395 | 1404 |
1396 void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { | 1405 void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { |
1397 std::vector<EnabledStateObserver*>::iterator it = | 1406 std::vector<EnabledStateObserver*>::iterator it = |
(...skipping 20 matching lines...) Expand all Loading... | |
1418 | 1427 |
1419 bool TraceLog::BufferIsFull() const { | 1428 bool TraceLog::BufferIsFull() const { |
1420 AutoLock lock(lock_); | 1429 AutoLock lock(lock_); |
1421 return logged_events_->IsFull(); | 1430 return logged_events_->IsFull(); |
1422 } | 1431 } |
1423 | 1432 |
1424 TraceBuffer* TraceLog::CreateTraceBuffer() { | 1433 TraceBuffer* TraceLog::CreateTraceBuffer() { |
1425 Options options = trace_options(); | 1434 Options options = trace_options(); |
1426 if (options & RECORD_CONTINUOUSLY) | 1435 if (options & RECORD_CONTINUOUSLY) |
1427 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); | 1436 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); |
1428 else if (options & MONITOR_SAMPLING) | 1437 else if ((options & ENABLE_SAMPLING) && mode_ == MONITORING_MODE) |
1429 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); | 1438 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); |
1430 else if (options & ECHO_TO_CONSOLE) | 1439 else if (options & ECHO_TO_CONSOLE) |
1431 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); | 1440 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); |
1432 return new TraceBufferVector(); | 1441 return new TraceBufferVector(); |
1433 } | 1442 } |
1434 | 1443 |
1435 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( | 1444 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( |
1436 TraceEventHandle* handle, bool check_buffer_is_full) { | 1445 TraceEventHandle* handle, bool check_buffer_is_full) { |
1437 lock_.AssertAcquired(); | 1446 lock_.AssertAcquired(); |
1438 | 1447 |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1762 if (!found) { | 1771 if (!found) { |
1763 if (existing_names.size()) | 1772 if (existing_names.size()) |
1764 existing_name->second.push_back(','); | 1773 existing_name->second.push_back(','); |
1765 existing_name->second.append(new_name); | 1774 existing_name->second.append(new_name); |
1766 } | 1775 } |
1767 } | 1776 } |
1768 } | 1777 } |
1769 } | 1778 } |
1770 | 1779 |
1771 std::string console_message; | 1780 std::string console_message; |
1772 if ((*category_group_enabled & ENABLED_FOR_RECORDING)) { | 1781 if (*category_group_enabled & |
1782 (ENABLED_FOR_RECORDING | ENABLED_FOR_MONITORING)) { | |
1773 OptionalAutoLock lock(lock_); | 1783 OptionalAutoLock lock(lock_); |
1774 | 1784 |
1775 TraceEvent* trace_event = NULL; | 1785 TraceEvent* trace_event = NULL; |
1776 if (thread_local_event_buffer) { | 1786 if (thread_local_event_buffer) { |
1777 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); | 1787 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); |
1778 } else { | 1788 } else { |
1779 lock.EnsureAcquired(); | 1789 lock.EnsureAcquired(); |
1780 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); | 1790 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); |
1781 } | 1791 } |
1782 | 1792 |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2312 } | 2322 } |
2313 | 2323 |
2314 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 2324 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
2315 if (*category_group_enabled_) { | 2325 if (*category_group_enabled_) { |
2316 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, | 2326 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, |
2317 name_, event_handle_); | 2327 name_, event_handle_); |
2318 } | 2328 } |
2319 } | 2329 } |
2320 | 2330 |
2321 } // namespace trace_event_internal | 2331 } // namespace trace_event_internal |
OLD | NEW |