| 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 : mode_(DISABLED), | 1110 : enabled_(false), |
| 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), RECORDING_MODE, ECHO_TO_CONSOLE); | 1156 SetEnabled(CategoryFilter(filter), 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 (mode_ == RECORDING_MODE && | 1195 if (enabled_ && category_filter_.IsCategoryGroupEnabled(category_group)) |
| 1196 category_filter_.IsCategoryGroupEnabled(category_group)) | |
| 1197 enabled_flag |= ENABLED_FOR_RECORDING; | 1196 enabled_flag |= ENABLED_FOR_RECORDING; |
| 1198 else if (mode_ == MONITORING_MODE && | |
| 1199 category_filter_.IsCategoryGroupEnabled(category_group)) | |
| 1200 enabled_flag |= ENABLED_FOR_MONITORING; | |
| 1201 if (event_callback_ && | 1197 if (event_callback_ && |
| 1202 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) | 1198 event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) |
| 1203 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; | 1199 enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; |
| 1204 g_category_group_enabled[category_index] = enabled_flag; | 1200 g_category_group_enabled[category_index] = enabled_flag; |
| 1205 } | 1201 } |
| 1206 | 1202 |
| 1207 void TraceLog::UpdateCategoryGroupEnabledFlags() { | 1203 void TraceLog::UpdateCategoryGroupEnabledFlags() { |
| 1208 for (int i = 0; i < g_category_index; i++) | 1204 for (int i = 0; i < g_category_index; i++) |
| 1209 UpdateCategoryGroupEnabledFlag(i); | 1205 UpdateCategoryGroupEnabledFlag(i); |
| 1210 } | 1206 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1253 void TraceLog::GetKnownCategoryGroups( | 1249 void TraceLog::GetKnownCategoryGroups( |
| 1254 std::vector<std::string>* category_groups) { | 1250 std::vector<std::string>* category_groups) { |
| 1255 AutoLock lock(lock_); | 1251 AutoLock lock(lock_); |
| 1256 category_groups->push_back( | 1252 category_groups->push_back( |
| 1257 g_category_groups[g_category_trace_event_overhead]); | 1253 g_category_groups[g_category_trace_event_overhead]); |
| 1258 for (int i = g_num_builtin_categories; i < g_category_index; i++) | 1254 for (int i = g_num_builtin_categories; i < g_category_index; i++) |
| 1259 category_groups->push_back(g_category_groups[i]); | 1255 category_groups->push_back(g_category_groups[i]); |
| 1260 } | 1256 } |
| 1261 | 1257 |
| 1262 void TraceLog::SetEnabled(const CategoryFilter& category_filter, | 1258 void TraceLog::SetEnabled(const CategoryFilter& category_filter, |
| 1263 Mode mode, | |
| 1264 Options options) { | 1259 Options options) { |
| 1265 std::vector<EnabledStateObserver*> observer_list; | 1260 std::vector<EnabledStateObserver*> observer_list; |
| 1266 { | 1261 { |
| 1267 AutoLock lock(lock_); | 1262 AutoLock lock(lock_); |
| 1268 | 1263 |
| 1269 // Can't enable tracing when Flush() is in progress. | 1264 // Can't enable tracing when Flush() is in progress. |
| 1270 DCHECK(!flush_message_loop_proxy_.get()); | 1265 DCHECK(!flush_message_loop_proxy_.get()); |
| 1271 | 1266 |
| 1272 Options old_options = trace_options(); | 1267 Options old_options = trace_options(); |
| 1273 | 1268 |
| 1274 if (IsEnabled()) { | 1269 if (enabled_) { |
| 1275 if (options != old_options) { | 1270 if (options != old_options) { |
| 1276 DLOG(ERROR) << "Attemting to re-enable tracing with a different " | 1271 DLOG(ERROR) << "Attemting to re-enable tracing with a different " |
| 1277 << "set of options."; | 1272 << "set of options."; |
| 1278 } | 1273 } |
| 1279 | 1274 |
| 1280 if (mode != mode_) { | |
| 1281 DLOG(ERROR) << "Attemting to re-enable tracing with a different mode."; | |
| 1282 } | |
| 1283 | |
| 1284 category_filter_.Merge(category_filter); | 1275 category_filter_.Merge(category_filter); |
| 1285 UpdateCategoryGroupEnabledFlags(); | 1276 UpdateCategoryGroupEnabledFlags(); |
| 1286 return; | 1277 return; |
| 1287 } | 1278 } |
| 1288 | 1279 |
| 1289 if (dispatching_to_observer_list_) { | 1280 if (dispatching_to_observer_list_) { |
| 1290 DLOG(ERROR) << | 1281 DLOG(ERROR) << |
| 1291 "Cannot manipulate TraceLog::Enabled state from an observer."; | 1282 "Cannot manipulate TraceLog::Enabled state from an observer."; |
| 1292 return; | 1283 return; |
| 1293 } | 1284 } |
| 1294 | 1285 |
| 1295 mode_ = mode; | 1286 enabled_ = true; |
| 1296 | 1287 |
| 1297 if (options != old_options) { | 1288 if (options != old_options) { |
| 1298 subtle::NoBarrier_Store(&trace_options_, options); | 1289 subtle::NoBarrier_Store(&trace_options_, options); |
| 1299 UseNextTraceBuffer(); | 1290 UseNextTraceBuffer(); |
| 1300 } | 1291 } |
| 1301 | 1292 |
| 1302 num_traces_recorded_++; | 1293 num_traces_recorded_++; |
| 1303 | 1294 |
| 1304 category_filter_ = CategoryFilter(category_filter); | 1295 category_filter_ = CategoryFilter(category_filter); |
| 1305 UpdateCategoryGroupEnabledFlags(); | 1296 UpdateCategoryGroupEnabledFlags(); |
| 1306 | 1297 |
| 1307 if (options & ENABLE_SAMPLING) { | 1298 if ((options & ENABLE_SAMPLING) || (options & MONITOR_SAMPLING)) { |
| 1308 sampling_thread_.reset(new TraceSamplingThread); | 1299 sampling_thread_.reset(new TraceSamplingThread); |
| 1309 sampling_thread_->RegisterSampleBucket( | 1300 sampling_thread_->RegisterSampleBucket( |
| 1310 &g_trace_state[0], | 1301 &g_trace_state[0], |
| 1311 "bucket0", | 1302 "bucket0", |
| 1312 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | 1303 Bind(&TraceSamplingThread::DefaultSamplingCallback)); |
| 1313 sampling_thread_->RegisterSampleBucket( | 1304 sampling_thread_->RegisterSampleBucket( |
| 1314 &g_trace_state[1], | 1305 &g_trace_state[1], |
| 1315 "bucket1", | 1306 "bucket1", |
| 1316 Bind(&TraceSamplingThread::DefaultSamplingCallback)); | 1307 Bind(&TraceSamplingThread::DefaultSamplingCallback)); |
| 1317 sampling_thread_->RegisterSampleBucket( | 1308 sampling_thread_->RegisterSampleBucket( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1343 } | 1334 } |
| 1344 | 1335 |
| 1345 void TraceLog::SetDisabled() { | 1336 void TraceLog::SetDisabled() { |
| 1346 AutoLock lock(lock_); | 1337 AutoLock lock(lock_); |
| 1347 SetDisabledWhileLocked(); | 1338 SetDisabledWhileLocked(); |
| 1348 } | 1339 } |
| 1349 | 1340 |
| 1350 void TraceLog::SetDisabledWhileLocked() { | 1341 void TraceLog::SetDisabledWhileLocked() { |
| 1351 lock_.AssertAcquired(); | 1342 lock_.AssertAcquired(); |
| 1352 | 1343 |
| 1353 if (!IsEnabled()) | 1344 if (!enabled_) |
| 1354 return; | 1345 return; |
| 1355 | 1346 |
| 1356 if (dispatching_to_observer_list_) { | 1347 if (dispatching_to_observer_list_) { |
| 1357 DLOG(ERROR) | 1348 DLOG(ERROR) |
| 1358 << "Cannot manipulate TraceLog::Enabled state from an observer."; | 1349 << "Cannot manipulate TraceLog::Enabled state from an observer."; |
| 1359 return; | 1350 return; |
| 1360 } | 1351 } |
| 1361 | 1352 |
| 1362 mode_ = DISABLED; | 1353 enabled_ = false; |
| 1363 | 1354 |
| 1364 if (sampling_thread_.get()) { | 1355 if (sampling_thread_.get()) { |
| 1365 base::ThreadRestrictions::SetIOAllowed(true); | |
| 1366 | |
| 1367 // Stop the sampling thread. | 1356 // Stop the sampling thread. |
| 1368 sampling_thread_->Stop(); | 1357 sampling_thread_->Stop(); |
| 1369 lock_.Release(); | 1358 lock_.Release(); |
| 1370 PlatformThread::Join(sampling_thread_handle_); | 1359 PlatformThread::Join(sampling_thread_handle_); |
| 1371 lock_.Acquire(); | 1360 lock_.Acquire(); |
| 1372 sampling_thread_handle_ = PlatformThreadHandle(); | 1361 sampling_thread_handle_ = PlatformThreadHandle(); |
| 1373 sampling_thread_.reset(); | 1362 sampling_thread_.reset(); |
| 1374 | |
| 1375 base::ThreadRestrictions::SetIOAllowed(false); | |
| 1376 } | 1363 } |
| 1377 | 1364 |
| 1378 category_filter_.Clear(); | 1365 category_filter_.Clear(); |
| 1379 subtle::NoBarrier_Store(&watch_category_, 0); | 1366 subtle::NoBarrier_Store(&watch_category_, 0); |
| 1380 watch_event_name_ = ""; | 1367 watch_event_name_ = ""; |
| 1381 UpdateCategoryGroupEnabledFlags(); | 1368 UpdateCategoryGroupEnabledFlags(); |
| 1382 AddMetadataEventsWhileLocked(); | 1369 AddMetadataEventsWhileLocked(); |
| 1383 | 1370 |
| 1384 dispatching_to_observer_list_ = true; | 1371 dispatching_to_observer_list_ = true; |
| 1385 std::vector<EnabledStateObserver*> observer_list = | 1372 std::vector<EnabledStateObserver*> observer_list = |
| 1386 enabled_state_observer_list_; | 1373 enabled_state_observer_list_; |
| 1387 | 1374 |
| 1388 { | 1375 { |
| 1389 // Dispatch to observers outside the lock in case the observer triggers a | 1376 // Dispatch to observers outside the lock in case the observer triggers a |
| 1390 // trace event. | 1377 // trace event. |
| 1391 AutoUnlock unlock(lock_); | 1378 AutoUnlock unlock(lock_); |
| 1392 for (size_t i = 0; i < observer_list.size(); ++i) | 1379 for (size_t i = 0; i < observer_list.size(); ++i) |
| 1393 observer_list[i]->OnTraceLogDisabled(); | 1380 observer_list[i]->OnTraceLogDisabled(); |
| 1394 } | 1381 } |
| 1395 dispatching_to_observer_list_ = false; | 1382 dispatching_to_observer_list_ = false; |
| 1396 } | 1383 } |
| 1397 | 1384 |
| 1398 int TraceLog::GetNumTracesRecorded() { | 1385 int TraceLog::GetNumTracesRecorded() { |
| 1399 AutoLock lock(lock_); | 1386 AutoLock lock(lock_); |
| 1400 if (!IsEnabled()) | 1387 if (!enabled_) |
| 1401 return -1; | 1388 return -1; |
| 1402 return num_traces_recorded_; | 1389 return num_traces_recorded_; |
| 1403 } | 1390 } |
| 1404 | 1391 |
| 1405 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { | 1392 void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { |
| 1406 enabled_state_observer_list_.push_back(listener); | 1393 enabled_state_observer_list_.push_back(listener); |
| 1407 } | 1394 } |
| 1408 | 1395 |
| 1409 void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { | 1396 void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { |
| 1410 std::vector<EnabledStateObserver*>::iterator it = | 1397 std::vector<EnabledStateObserver*>::iterator it = |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1431 | 1418 |
| 1432 bool TraceLog::BufferIsFull() const { | 1419 bool TraceLog::BufferIsFull() const { |
| 1433 AutoLock lock(lock_); | 1420 AutoLock lock(lock_); |
| 1434 return logged_events_->IsFull(); | 1421 return logged_events_->IsFull(); |
| 1435 } | 1422 } |
| 1436 | 1423 |
| 1437 TraceBuffer* TraceLog::CreateTraceBuffer() { | 1424 TraceBuffer* TraceLog::CreateTraceBuffer() { |
| 1438 Options options = trace_options(); | 1425 Options options = trace_options(); |
| 1439 if (options & RECORD_CONTINUOUSLY) | 1426 if (options & RECORD_CONTINUOUSLY) |
| 1440 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); | 1427 return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); |
| 1441 else if ((options & ENABLE_SAMPLING) && mode_ == MONITORING_MODE) | 1428 else if (options & MONITOR_SAMPLING) |
| 1442 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); | 1429 return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); |
| 1443 else if (options & ECHO_TO_CONSOLE) | 1430 else if (options & ECHO_TO_CONSOLE) |
| 1444 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); | 1431 return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); |
| 1445 return new TraceBufferVector(); | 1432 return new TraceBufferVector(); |
| 1446 } | 1433 } |
| 1447 | 1434 |
| 1448 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( | 1435 TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( |
| 1449 TraceEventHandle* handle, bool check_buffer_is_full) { | 1436 TraceEventHandle* handle, bool check_buffer_is_full) { |
| 1450 lock_.AssertAcquired(); | 1437 lock_.AssertAcquired(); |
| 1451 | 1438 |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1775 if (!found) { | 1762 if (!found) { |
| 1776 if (existing_names.size()) | 1763 if (existing_names.size()) |
| 1777 existing_name->second.push_back(','); | 1764 existing_name->second.push_back(','); |
| 1778 existing_name->second.append(new_name); | 1765 existing_name->second.append(new_name); |
| 1779 } | 1766 } |
| 1780 } | 1767 } |
| 1781 } | 1768 } |
| 1782 } | 1769 } |
| 1783 | 1770 |
| 1784 std::string console_message; | 1771 std::string console_message; |
| 1785 if (*category_group_enabled & | 1772 if ((*category_group_enabled & ENABLED_FOR_RECORDING)) { |
| 1786 (ENABLED_FOR_RECORDING | ENABLED_FOR_MONITORING)) { | |
| 1787 OptionalAutoLock lock(lock_); | 1773 OptionalAutoLock lock(lock_); |
| 1788 | 1774 |
| 1789 TraceEvent* trace_event = NULL; | 1775 TraceEvent* trace_event = NULL; |
| 1790 if (thread_local_event_buffer) { | 1776 if (thread_local_event_buffer) { |
| 1791 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); | 1777 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); |
| 1792 } else { | 1778 } else { |
| 1793 lock.EnsureAcquired(); | 1779 lock.EnsureAcquired(); |
| 1794 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); | 1780 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); |
| 1795 } | 1781 } |
| 1796 | 1782 |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2326 } | 2312 } |
| 2327 | 2313 |
| 2328 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 2314 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
| 2329 if (*category_group_enabled_) { | 2315 if (*category_group_enabled_) { |
| 2330 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, | 2316 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, |
| 2331 name_, event_handle_); | 2317 name_, event_handle_); |
| 2332 } | 2318 } |
| 2333 } | 2319 } |
| 2334 | 2320 |
| 2335 } // namespace trace_event_internal | 2321 } // namespace trace_event_internal |
| OLD | NEW |