| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/trace_event/trace_log.h" | 5 #include "base/trace_event/trace_log.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" | 34 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" |
| 35 #include "base/trace_event/memory_dump_manager.h" | 35 #include "base/trace_event/memory_dump_manager.h" |
| 36 #include "base/trace_event/memory_dump_provider.h" | 36 #include "base/trace_event/memory_dump_provider.h" |
| 37 #include "base/trace_event/process_memory_dump.h" | 37 #include "base/trace_event/process_memory_dump.h" |
| 38 #include "base/trace_event/trace_buffer.h" | 38 #include "base/trace_event/trace_buffer.h" |
| 39 #include "base/trace_event/trace_event.h" | 39 #include "base/trace_event/trace_event.h" |
| 40 #include "base/trace_event/trace_event_synthetic_delay.h" | 40 #include "base/trace_event/trace_event_synthetic_delay.h" |
| 41 #include "base/trace_event/trace_sampling_thread.h" | 41 #include "base/trace_event/trace_sampling_thread.h" |
| 42 #include "build/build_config.h" | 42 #include "build/build_config.h" |
| 43 | 43 |
| 44 |
| 44 #if defined(OS_WIN) | 45 #if defined(OS_WIN) |
| 45 #include "base/trace_event/trace_event_etw_export_win.h" | 46 #include "base/trace_event/trace_event_etw_export_win.h" |
| 46 #endif | 47 #endif |
| 47 | 48 |
| 48 // The thread buckets for the sampling profiler. | 49 // The thread buckets for the sampling profiler. |
| 49 BASE_EXPORT TRACE_EVENT_API_ATOMIC_WORD g_trace_state[3]; | 50 BASE_EXPORT TRACE_EVENT_API_ATOMIC_WORD g_trace_state[3]; |
| 50 | 51 |
| 51 namespace base { | 52 namespace base { |
| 52 namespace internal { | 53 namespace internal { |
| 53 | 54 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 locked_ = true; | 199 locked_ = true; |
| 199 } | 200 } |
| 200 } | 201 } |
| 201 | 202 |
| 202 private: | 203 private: |
| 203 Lock* lock_; | 204 Lock* lock_; |
| 204 bool locked_; | 205 bool locked_; |
| 205 DISALLOW_COPY_AND_ASSIGN(OptionalAutoLock); | 206 DISALLOW_COPY_AND_ASSIGN(OptionalAutoLock); |
| 206 }; | 207 }; |
| 207 | 208 |
| 209 bool TraceLog::use_v2 = false; |
| 210 |
| 208 class TraceLog::ThreadLocalEventBuffer | 211 class TraceLog::ThreadLocalEventBuffer |
| 209 : public MessageLoop::DestructionObserver, | 212 : public MessageLoop::DestructionObserver, |
| 210 public MemoryDumpProvider { | 213 public MemoryDumpProvider { |
| 211 public: | 214 public: |
| 215 v2::ZeroCopyTraceBufferWriter* v2; |
| 216 |
| 212 explicit ThreadLocalEventBuffer(TraceLog* trace_log); | 217 explicit ThreadLocalEventBuffer(TraceLog* trace_log); |
| 213 ~ThreadLocalEventBuffer() override; | 218 ~ThreadLocalEventBuffer() override; |
| 214 | 219 |
| 215 TraceEvent* AddTraceEvent(TraceEventHandle* handle); | 220 TraceEvent* AddTraceEvent(TraceEventHandle* handle); |
| 216 | 221 |
| 217 TraceEvent* GetEventByHandle(TraceEventHandle handle) { | 222 TraceEvent* GetEventByHandle(TraceEventHandle handle) { |
| 218 if (!chunk_ || handle.chunk_seq != chunk_->seq() || | 223 if (!chunk_ || handle.chunk_seq != chunk_->seq() || |
| 219 handle.chunk_index != chunk_index_) { | 224 handle.chunk_index != chunk_index_) { |
| 220 return nullptr; | 225 return nullptr; |
| 221 } | 226 } |
| 222 | 227 |
| 223 return chunk_->GetEventAt(handle.event_index); | 228 return chunk_->GetEventAt(handle.event_index); |
| 224 } | 229 } |
| 225 | 230 |
| 226 int generation() const { return generation_; } | 231 int generation() const { return generation_; } |
| 227 | 232 |
| 233 v2::ZeroCopyTraceBufferWriter v2_wri; |
| 234 |
| 228 private: | 235 private: |
| 229 // MessageLoop::DestructionObserver | 236 // MessageLoop::DestructionObserver |
| 230 void WillDestroyCurrentMessageLoop() override; | 237 void WillDestroyCurrentMessageLoop() override; |
| 231 | 238 |
| 232 // MemoryDumpProvider implementation. | 239 // MemoryDumpProvider implementation. |
| 233 bool OnMemoryDump(const MemoryDumpArgs& args, | 240 bool OnMemoryDump(const MemoryDumpArgs& args, |
| 234 ProcessMemoryDump* pmd) override; | 241 ProcessMemoryDump* pmd) override; |
| 235 | 242 |
| 236 void FlushWhileLocked(); | 243 void FlushWhileLocked(); |
| 237 | 244 |
| 238 void CheckThisIsCurrentBuffer() const { | 245 void CheckThisIsCurrentBuffer() const { |
| 239 DCHECK(trace_log_->thread_local_event_buffer_.Get() == this); | 246 DCHECK(trace_log_->thread_local_event_buffer_.Get() == this); |
| 240 } | 247 } |
| 241 | 248 |
| 242 // Since TraceLog is a leaky singleton, trace_log_ will always be valid | 249 // Since TraceLog is a leaky singleton, trace_log_ will always be valid |
| 243 // as long as the thread exists. | 250 // as long as the thread exists. |
| 244 TraceLog* trace_log_; | 251 TraceLog* trace_log_; |
| 245 std::unique_ptr<TraceBufferChunk> chunk_; | 252 std::unique_ptr<TraceBufferChunk> chunk_; |
| 246 size_t chunk_index_; | 253 size_t chunk_index_; |
| 247 int generation_; | 254 int generation_; |
| 248 | 255 |
| 249 DISALLOW_COPY_AND_ASSIGN(ThreadLocalEventBuffer); | 256 DISALLOW_COPY_AND_ASSIGN(ThreadLocalEventBuffer); |
| 250 }; | 257 }; |
| 251 | 258 |
| 252 TraceLog::ThreadLocalEventBuffer::ThreadLocalEventBuffer(TraceLog* trace_log) | 259 TraceLog::ThreadLocalEventBuffer::ThreadLocalEventBuffer(TraceLog* trace_log) |
| 253 : trace_log_(trace_log), | 260 : v2_wri(&trace_log->v2_rb, 42), |
| 261 trace_log_(trace_log), |
| 254 chunk_index_(0), | 262 chunk_index_(0), |
| 255 generation_(trace_log->generation()) { | 263 generation_(trace_log->generation()) { |
| 256 // ThreadLocalEventBuffer is created only if the thread has a message loop, so | 264 // ThreadLocalEventBuffer is created only if the thread has a message loop, so |
| 257 // the following message_loop won't be NULL. | 265 // the following message_loop won't be NULL. |
| 258 MessageLoop* message_loop = MessageLoop::current(); | 266 MessageLoop* message_loop = MessageLoop::current(); |
| 259 message_loop->AddDestructionObserver(this); | 267 message_loop->AddDestructionObserver(this); |
| 260 | 268 |
| 261 // This is to report the local memory usage when memory-infra is enabled. | 269 // This is to report the local memory usage when memory-infra is enabled. |
| 262 MemoryDumpManager::GetInstance()->RegisterDumpProvider( | 270 MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| 263 this, "ThreadLocalEventBuffer", ThreadTaskRunnerHandle::Get()); | 271 this, "ThreadLocalEventBuffer", ThreadTaskRunnerHandle::Get()); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 process_sort_index_(0), | 358 process_sort_index_(0), |
| 351 process_id_hash_(0), | 359 process_id_hash_(0), |
| 352 process_id_(0), | 360 process_id_(0), |
| 353 watch_category_(0), | 361 watch_category_(0), |
| 354 trace_options_(kInternalRecordUntilFull), | 362 trace_options_(kInternalRecordUntilFull), |
| 355 sampling_thread_handle_(0), | 363 sampling_thread_handle_(0), |
| 356 trace_config_(TraceConfig()), | 364 trace_config_(TraceConfig()), |
| 357 event_callback_trace_config_(TraceConfig()), | 365 event_callback_trace_config_(TraceConfig()), |
| 358 thread_shared_chunk_index_(0), | 366 thread_shared_chunk_index_(0), |
| 359 generation_(0), | 367 generation_(0), |
| 360 use_worker_thread_(false) { | 368 use_worker_thread_(false), |
| 369 v2_rb(&v2_buf[0], sizeof(v2_buf)) { |
| 361 // Trace is enabled or disabled on one thread while other threads are | 370 // Trace is enabled or disabled on one thread while other threads are |
| 362 // accessing the enabled flag. We don't care whether edge-case events are | 371 // accessing the enabled flag. We don't care whether edge-case events are |
| 363 // traced or not, so we allow races on the enabled flag to keep the trace | 372 // traced or not, so we allow races on the enabled flag to keep the trace |
| 364 // macros fast. | 373 // macros fast. |
| 365 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: | 374 // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: |
| 366 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, | 375 // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, |
| 367 // sizeof(g_category_group_enabled), | 376 // sizeof(g_category_group_enabled), |
| 368 // "trace_event category enabled"); | 377 // "trace_event category enabled"); |
| 369 for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) { | 378 for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) { |
| 370 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], | 379 ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 | 571 |
| 563 void TraceLog::GetKnownCategoryGroups( | 572 void TraceLog::GetKnownCategoryGroups( |
| 564 std::vector<std::string>* category_groups) { | 573 std::vector<std::string>* category_groups) { |
| 565 AutoLock lock(lock_); | 574 AutoLock lock(lock_); |
| 566 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index); | 575 size_t category_index = base::subtle::NoBarrier_Load(&g_category_index); |
| 567 for (size_t i = g_num_builtin_categories; i < category_index; i++) | 576 for (size_t i = g_num_builtin_categories; i < category_index; i++) |
| 568 category_groups->push_back(g_category_groups[i]); | 577 category_groups->push_back(g_category_groups[i]); |
| 569 } | 578 } |
| 570 | 579 |
| 571 void TraceLog::SetEnabled(const TraceConfig& trace_config, Mode mode) { | 580 void TraceLog::SetEnabled(const TraceConfig& trace_config, Mode mode) { |
| 581 memset(v2_buf, 0, sizeof(v2_buf)); |
| 572 std::vector<EnabledStateObserver*> observer_list; | 582 std::vector<EnabledStateObserver*> observer_list; |
| 573 { | 583 { |
| 574 AutoLock lock(lock_); | 584 AutoLock lock(lock_); |
| 575 | 585 |
| 576 // Can't enable tracing when Flush() is in progress. | 586 // Can't enable tracing when Flush() is in progress. |
| 577 DCHECK(!flush_task_runner_); | 587 DCHECK(!flush_task_runner_); |
| 578 | 588 |
| 579 InternalTraceOptions new_options = | 589 InternalTraceOptions new_options = |
| 580 GetInternalOptionsFromTraceConfig(trace_config); | 590 GetInternalOptionsFromTraceConfig(trace_config); |
| 581 | 591 |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1244 TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id, | 1254 TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id, |
| 1245 num_args, arg_names, arg_types, arg_values, | 1255 num_args, arg_names, arg_types, arg_values, |
| 1246 convertable_values); | 1256 convertable_values); |
| 1247 #endif // OS_WIN | 1257 #endif // OS_WIN |
| 1248 | 1258 |
| 1249 std::string console_message; | 1259 std::string console_message; |
| 1250 if (*category_group_enabled & ENABLED_FOR_RECORDING) { | 1260 if (*category_group_enabled & ENABLED_FOR_RECORDING) { |
| 1251 OptionalAutoLock lock(&lock_); | 1261 OptionalAutoLock lock(&lock_); |
| 1252 | 1262 |
| 1253 TraceEvent* trace_event = NULL; | 1263 TraceEvent* trace_event = NULL; |
| 1264 if (TraceLog::use_v2) { |
| 1265 v2::TraceEventHandle evt = thread_local_event_buffer->v2_wri.AddEvent(); |
| 1266 evt->set_thread_id(thread_id); |
| 1267 evt->set_timestamp(offset_event_timestamp.ToInternalValue()); |
| 1268 evt->set_thread_timestamp(thread_now.ToInternalValue()); |
| 1269 evt->set_type((::tracing::Event_Type) phase); |
| 1270 evt->set_category_id(static_cast<uint32_t>((uintptr_t)category_group_enabl
ed)); |
| 1271 evt->set_name_id(static_cast<uint32_t>((uintptr_t)name)); |
| 1272 evt->set_id(id); |
| 1273 if (num_args > 0) { |
| 1274 tracing::EventArgsSimple* v2_args = evt->add_args_simple(); |
| 1275 |
| 1276 v2_args->set_arg_1_name_idx((uintptr_t) arg_names[0]); |
| 1277 switch(arg_types[0]) { |
| 1278 case TRACE_VALUE_TYPE_POINTER: { |
| 1279 // Super hack to test future convertable items. Assume that if a |
| 1280 // pointer was passed it was a pointer to a TraceEventHandle. |
| 1281 v2::TraceEventHandle* h = reinterpret_cast<v2::TraceEventHandle*>(
(uintptr_t)arg_values[0]); |
| 1282 *h = std::move(evt); |
| 1283 } |
| 1284 break; |
| 1285 case TRACE_VALUE_TYPE_BOOL: |
| 1286 v2_args->set_arg_1_bool_value(arg_values[0]); break; |
| 1287 // I am too lazy for all the cases :P |
| 1288 default: |
| 1289 v2_args->set_arg_1_int_value(arg_values[0]); break; |
| 1290 break; |
| 1291 } |
| 1292 |
| 1293 if (num_args > 1) { |
| 1294 v2_args->set_arg_2_name_idx((uintptr_t) arg_names[1]); |
| 1295 switch(arg_types[1]) { |
| 1296 case TRACE_VALUE_TYPE_BOOL: |
| 1297 v2_args->set_arg_2_bool_value(arg_values[1]); break; |
| 1298 // I am too lazy for all the cases :P |
| 1299 default: |
| 1300 v2_args->set_arg_2_int_value(arg_values[1]); break; |
| 1301 break; |
| 1302 } |
| 1303 } |
| 1304 } // if num_args > 0 |
| 1305 } else { |
| 1306 |
| 1254 if (thread_local_event_buffer) { | 1307 if (thread_local_event_buffer) { |
| 1255 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); | 1308 trace_event = thread_local_event_buffer->AddTraceEvent(&handle); |
| 1256 } else { | 1309 } else { |
| 1257 lock.EnsureAcquired(); | 1310 lock.EnsureAcquired(); |
| 1258 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); | 1311 trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); |
| 1259 } | 1312 } |
| 1260 | 1313 |
| 1261 if (trace_event) { | 1314 if (trace_event) { |
| 1262 trace_event->Initialize(thread_id, | 1315 trace_event->Initialize(thread_id, |
| 1263 offset_event_timestamp, | 1316 offset_event_timestamp, |
| 1264 thread_now, | 1317 thread_now, |
| 1265 phase, | 1318 phase, |
| 1266 category_group_enabled, | 1319 category_group_enabled, |
| 1267 name, | 1320 name, |
| 1268 scope, | 1321 scope, |
| 1269 id, | 1322 id, |
| 1270 bind_id, | 1323 bind_id, |
| 1271 num_args, | 1324 num_args, |
| 1272 arg_names, | 1325 arg_names, |
| 1273 arg_types, | 1326 arg_types, |
| 1274 arg_values, | 1327 arg_values, |
| 1275 convertable_values, | 1328 convertable_values, |
| 1276 flags); | 1329 flags); |
| 1277 | 1330 } // else v2 |
| 1278 #if defined(OS_ANDROID) | 1331 #if defined(OS_ANDROID) |
| 1279 trace_event->SendToATrace(); | 1332 trace_event->SendToATrace(); |
| 1280 #endif | 1333 #endif |
| 1281 } | 1334 } |
| 1282 | 1335 |
| 1283 if (trace_options() & kInternalEchoToConsole) { | 1336 if (trace_options() & kInternalEchoToConsole) { |
| 1284 console_message = EventToConsoleMessage( | 1337 console_message = EventToConsoleMessage( |
| 1285 phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase, | 1338 phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase, |
| 1286 timestamp, trace_event); | 1339 timestamp, trace_event); |
| 1287 } | 1340 } |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1744 } | 1797 } |
| 1745 | 1798 |
| 1746 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 1799 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
| 1747 if (*category_group_enabled_) { | 1800 if (*category_group_enabled_) { |
| 1748 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, | 1801 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_, |
| 1749 event_handle_); | 1802 event_handle_); |
| 1750 } | 1803 } |
| 1751 } | 1804 } |
| 1752 | 1805 |
| 1753 } // namespace trace_event_internal | 1806 } // namespace trace_event_internal |
| OLD | NEW |