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 3 // found in the LICENSE file. 4 5 #ifndef BASE_TRACE_EVENT_TRACE_LOG_H_ 6 #define BASE_TRACE_EVENT_TRACE_LOG_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <string> 13 #include <vector> 14 15 #include "base/atomicops.h" 16 #include "base/containers/hash_tables.h" 17 #include "base/gtest_prod_util.h" 18 #include "base/macros.h" 19 #include "base/memory/scoped_vector.h" 20 #include "base/trace_event/memory_dump_provider.h" 21 #include "base/trace_event/trace_config.h" 22 #include "base/trace_event/trace_event_impl.h" 23 #include "build/build_config.h" 24 25 namespace base { 26 27 template <typename Type> 28 struct DefaultSingletonTraits; 29 class RefCountedString; 30 31 namespace trace_event { 32 33 class TraceBuffer; 34 class TraceBufferChunk; 35 class TraceEvent; 36 class TraceEventMemoryOverhead; 37 class TraceSamplingThread; 38 39 struct BASE_EXPORT TraceLogStatus { 40 TraceLogStatus(); 41 ~TraceLogStatus(); 42 uint32_t event_capacity; 43 uint32_t event_count; 44 }; 45 46 class BASE_EXPORT TraceLog : public MemoryDumpProvider { 47 public: 48 enum Mode { 49 DISABLED = 0, 50 RECORDING_MODE 51 }; 52 53 // The pointer returned from GetCategoryGroupEnabledInternal() points to a 54 // value with zero or more of the following bits. Used in this class only. 55 // The TRACE_EVENT macros should only use the value as a bool. 56 // These values must be in sync with macro values in TraceEvent.h in Blink. 57 enum CategoryGroupEnabledFlags { 58 // Category group enabled for the recording mode. 59 ENABLED_FOR_RECORDING = 1 << 0, 60 // Category group enabled by SetEventCallbackEnabled(). 61 ENABLED_FOR_EVENT_CALLBACK = 1 << 2, 62 // Category group enabled to export events to ETW. 63 ENABLED_FOR_ETW_EXPORT = 1 << 3 64 }; 65 66 static TraceLog* GetInstance(); 67 68 // Get set of known category groups. This can change as new code paths are 69 // reached. The known category groups are inserted into |category_groups|. 70 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); 71 72 // Retrieves a copy (for thread-safety) of the current TraceConfig. 73 TraceConfig GetCurrentTraceConfig() const; 74 75 // Initializes the thread-local event buffer, if not already initialized and 76 // if the current thread supports that (has a message loop). 77 void InitializeThreadLocalEventBufferIfSupported(); 78 79 // Enables normal tracing (recording trace events in the trace buffer). 80 // See TraceConfig comments for details on how to control what categories 81 // will be traced. If tracing has already been enabled, |category_filter| will 82 // be merged into the current category filter. 83 void SetEnabled(const TraceConfig& trace_config, Mode mode); 84 85 // Disables normal tracing for all categories. 86 void SetDisabled(); 87 IsEnabled()88 bool IsEnabled() { return mode_ != DISABLED; } 89 90 // The number of times we have begun recording traces. If tracing is off, 91 // returns -1. If tracing is on, then it returns the number of times we have 92 // recorded a trace. By watching for this number to increment, you can 93 // passively discover when a new trace has begun. This is then used to 94 // implement the TRACE_EVENT_IS_NEW_TRACE() primitive. 95 int GetNumTracesRecorded(); 96 97 #if defined(OS_ANDROID) 98 void StartATrace(); 99 void StopATrace(); 100 void AddClockSyncMetadataEvent(); 101 #endif 102 103 // Enabled state listeners give a callback when tracing is enabled or 104 // disabled. This can be used to tie into other library's tracing systems 105 // on-demand. 106 class BASE_EXPORT EnabledStateObserver { 107 public: 108 virtual ~EnabledStateObserver() = default; 109 110 // Called just after the tracing system becomes enabled, outside of the 111 // |lock_|. TraceLog::IsEnabled() is true at this point. 112 virtual void OnTraceLogEnabled() = 0; 113 114 // Called just after the tracing system disables, outside of the |lock_|. 115 // TraceLog::IsEnabled() is false at this point. 116 virtual void OnTraceLogDisabled() = 0; 117 }; 118 void AddEnabledStateObserver(EnabledStateObserver* listener); 119 void RemoveEnabledStateObserver(EnabledStateObserver* listener); 120 bool HasEnabledStateObserver(EnabledStateObserver* listener) const; 121 122 // Asynchronous enabled state listeners. When tracing is enabled or disabled, 123 // for each observer, a task for invoking its appropriate callback is posted 124 // to the thread from which AddAsyncEnabledStateObserver() was called. This 125 // allows the observer to be safely destroyed, provided that it happens on the 126 // same thread that invoked AddAsyncEnabledStateObserver(). 127 class BASE_EXPORT AsyncEnabledStateObserver { 128 public: 129 virtual ~AsyncEnabledStateObserver() = default; 130 131 // Posted just after the tracing system becomes enabled, outside |lock_|. 132 // TraceLog::IsEnabled() is true at this point. 133 virtual void OnTraceLogEnabled() = 0; 134 135 // Posted just after the tracing system becomes disabled, outside |lock_|. 136 // TraceLog::IsEnabled() is false at this point. 137 virtual void OnTraceLogDisabled() = 0; 138 }; 139 void AddAsyncEnabledStateObserver( 140 WeakPtr<AsyncEnabledStateObserver> listener); 141 void RemoveAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener); 142 bool HasAsyncEnabledStateObserver(AsyncEnabledStateObserver* listener) const; 143 144 TraceLogStatus GetStatus() const; 145 bool BufferIsFull() const; 146 147 // Computes an estimate of the size of the TraceLog including all the retained 148 // objects. 149 void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); 150 151 // Not using base::Callback because of its limited by 7 parameters. 152 // Also, using primitive type allows directly passing callback from WebCore. 153 // WARNING: It is possible for the previously set callback to be called 154 // after a call to SetEventCallbackEnabled() that replaces or a call to 155 // SetEventCallbackDisabled() that disables the callback. 156 // This callback may be invoked on any thread. 157 // For TRACE_EVENT_PHASE_COMPLETE events, the client will still receive pairs 158 // of TRACE_EVENT_PHASE_BEGIN and TRACE_EVENT_PHASE_END events to keep the 159 // interface simple. 160 typedef void (*EventCallback)(TimeTicks timestamp, 161 char phase, 162 const unsigned char* category_group_enabled, 163 const char* name, 164 const char* scope, 165 unsigned long long id, 166 int num_args, 167 const char* const arg_names[], 168 const unsigned char arg_types[], 169 const unsigned long long arg_values[], 170 unsigned int flags); 171 172 // Enable tracing for EventCallback. 173 void SetEventCallbackEnabled(const TraceConfig& trace_config, 174 EventCallback cb); 175 void SetEventCallbackDisabled(); 176 void SetArgumentFilterPredicate( 177 const ArgumentFilterPredicate& argument_filter_predicate); 178 179 // Flush all collected events to the given output callback. The callback will 180 // be called one or more times either synchronously or asynchronously from 181 // the current thread with IPC-bite-size chunks. The string format is 182 // undefined. Use TraceResultBuffer to convert one or more trace strings to 183 // JSON. The callback can be null if the caller doesn't want any data. 184 // Due to the implementation of thread-local buffers, flush can't be 185 // done when tracing is enabled. If called when tracing is enabled, the 186 // callback will be called directly with (empty_string, false) to indicate 187 // the end of this unsuccessful flush. Flush does the serialization 188 // on the same thread if the caller doesn't set use_worker_thread explicitly. 189 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&, 190 bool has_more_events)> OutputCallback; 191 void Flush(const OutputCallback& cb, bool use_worker_thread = false); 192 193 // Cancels tracing and discards collected data. 194 void CancelTracing(const OutputCallback& cb); 195 196 // Called by TRACE_EVENT* macros, don't call this directly. 197 // The name parameter is a category group for example: 198 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") 199 static const unsigned char* GetCategoryGroupEnabled(const char* name); 200 static const char* GetCategoryGroupName( 201 const unsigned char* category_group_enabled); 202 203 // Called by TRACE_EVENT* macros, don't call this directly. 204 // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied 205 // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. 206 TraceEventHandle AddTraceEvent( 207 char phase, 208 const unsigned char* category_group_enabled, 209 const char* name, 210 const char* scope, 211 unsigned long long id, 212 int num_args, 213 const char** arg_names, 214 const unsigned char* arg_types, 215 const unsigned long long* arg_values, 216 std::unique_ptr<ConvertableToTraceFormat>* convertable_values, 217 unsigned int flags); 218 TraceEventHandle AddTraceEventWithBindId( 219 char phase, 220 const unsigned char* category_group_enabled, 221 const char* name, 222 const char* scope, 223 unsigned long long id, 224 unsigned long long bind_id, 225 int num_args, 226 const char** arg_names, 227 const unsigned char* arg_types, 228 const unsigned long long* arg_values, 229 std::unique_ptr<ConvertableToTraceFormat>* convertable_values, 230 unsigned int flags); 231 TraceEventHandle AddTraceEventWithProcessId( 232 char phase, 233 const unsigned char* category_group_enabled, 234 const char* name, 235 const char* scope, 236 unsigned long long id, 237 int process_id, 238 int num_args, 239 const char** arg_names, 240 const unsigned char* arg_types, 241 const unsigned long long* arg_values, 242 std::unique_ptr<ConvertableToTraceFormat>* convertable_values, 243 unsigned int flags); 244 TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( 245 char phase, 246 const unsigned char* category_group_enabled, 247 const char* name, 248 const char* scope, 249 unsigned long long id, 250 int thread_id, 251 const TimeTicks& timestamp, 252 int num_args, 253 const char** arg_names, 254 const unsigned char* arg_types, 255 const unsigned long long* arg_values, 256 std::unique_ptr<ConvertableToTraceFormat>* convertable_values, 257 unsigned int flags); 258 TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( 259 char phase, 260 const unsigned char* category_group_enabled, 261 const char* name, 262 const char* scope, 263 unsigned long long id, 264 unsigned long long bind_id, 265 int thread_id, 266 const TimeTicks& timestamp, 267 int num_args, 268 const char** arg_names, 269 const unsigned char* arg_types, 270 const unsigned long long* arg_values, 271 std::unique_ptr<ConvertableToTraceFormat>* convertable_values, 272 unsigned int flags); 273 274 // Adds a metadata event that will be written when the trace log is flushed. 275 void AddMetadataEvent( 276 const unsigned char* category_group_enabled, 277 const char* name, 278 int num_args, 279 const char** arg_names, 280 const unsigned char* arg_types, 281 const unsigned long long* arg_values, 282 std::unique_ptr<ConvertableToTraceFormat>* convertable_values, 283 unsigned int flags); 284 285 void UpdateTraceEventDuration(const unsigned char* category_group_enabled, 286 const char* name, 287 TraceEventHandle handle); 288 289 // For every matching event, the callback will be called. 290 typedef base::Callback<void()> WatchEventCallback; 291 void SetWatchEvent(const std::string& category_name, 292 const std::string& event_name, 293 const WatchEventCallback& callback); 294 // Cancel the watch event. If tracing is enabled, this may race with the 295 // watch event notification firing. 296 void CancelWatchEvent(); 297 process_id()298 int process_id() const { return process_id_; } 299 300 uint64_t MangleEventId(uint64_t id); 301 302 // Exposed for unittesting: 303 304 void WaitSamplingEventForTesting(); 305 306 // Allows deleting our singleton instance. 307 static void DeleteForTesting(); 308 309 // Allow tests to inspect TraceEvents. 310 TraceEvent* GetEventByHandle(TraceEventHandle handle); 311 312 void SetProcessID(int process_id); 313 314 // Process sort indices, if set, override the order of a process will appear 315 // relative to other processes in the trace viewer. Processes are sorted first 316 // on their sort index, ascending, then by their name, and then tid. 317 void SetProcessSortIndex(int sort_index); 318 319 // Sets the name of the process. 320 void SetProcessName(const std::string& process_name); 321 322 // Processes can have labels in addition to their names. Use labels, for 323 // instance, to list out the web page titles that a process is handling. 324 void UpdateProcessLabel(int label_id, const std::string& current_label); 325 void RemoveProcessLabel(int label_id); 326 327 // Thread sort indices, if set, override the order of a thread will appear 328 // within its process in the trace viewer. Threads are sorted first on their 329 // sort index, ascending, then by their name, and then tid. 330 void SetThreadSortIndex(PlatformThreadId thread_id, int sort_index); 331 332 // Allow setting an offset between the current TimeTicks time and the time 333 // that should be reported. 334 void SetTimeOffset(TimeDelta offset); 335 336 size_t GetObserverCountForTest() const; 337 338 // Call this method if the current thread may block the message loop to 339 // prevent the thread from using the thread-local buffer because the thread 340 // may not handle the flush request in time causing lost of unflushed events. 341 void SetCurrentThreadBlocksMessageLoop(); 342 343 #if defined(OS_WIN) 344 // This function is called by the ETW exporting module whenever the ETW 345 // keyword (flags) changes. This keyword indicates which categories should be 346 // exported, so whenever it changes, we adjust accordingly. 347 void UpdateETWCategoryGroupEnabledFlags(); 348 #endif 349 350 private: 351 typedef unsigned int InternalTraceOptions; 352 353 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 354 TraceBufferRingBufferGetReturnChunk); 355 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 356 TraceBufferRingBufferHalfIteration); 357 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 358 TraceBufferRingBufferFullIteration); 359 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, TraceBufferVectorReportFull); 360 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 361 ConvertTraceConfigToInternalOptions); 362 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, 363 TraceRecordAsMuchAsPossibleMode); 364 365 // This allows constructor and destructor to be private and usable only 366 // by the Singleton class. 367 friend struct DefaultSingletonTraits<TraceLog>; 368 369 // MemoryDumpProvider implementation. 370 bool OnMemoryDump(const MemoryDumpArgs& args, 371 ProcessMemoryDump* pmd) override; 372 373 // Enable/disable each category group based on the current mode_, 374 // category_filter_, event_callback_ and event_callback_category_filter_. 375 // Enable the category group in the enabled mode if category_filter_ matches 376 // the category group, or event_callback_ is not null and 377 // event_callback_category_filter_ matches the category group. 378 void UpdateCategoryGroupEnabledFlags(); 379 void UpdateCategoryGroupEnabledFlag(size_t category_index); 380 381 // Configure synthetic delays based on the values set in the current 382 // trace config. 383 void UpdateSyntheticDelaysFromTraceConfig(); 384 385 InternalTraceOptions GetInternalOptionsFromTraceConfig( 386 const TraceConfig& config); 387 388 class ThreadLocalEventBuffer; 389 class OptionalAutoLock; 390 struct RegisteredAsyncObserver; 391 392 TraceLog(); 393 ~TraceLog() override; 394 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); 395 void AddMetadataEventsWhileLocked(); 396 397 InternalTraceOptions trace_options() const { 398 return static_cast<InternalTraceOptions>( 399 subtle::NoBarrier_Load(&trace_options_)); 400 } 401 402 TraceBuffer* trace_buffer() const { return logged_events_.get(); } 403 TraceBuffer* CreateTraceBuffer(); 404 405 std::string EventToConsoleMessage(unsigned char phase, 406 const TimeTicks& timestamp, 407 TraceEvent* trace_event); 408 409 TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle, 410 bool check_buffer_is_full); 411 void CheckIfBufferIsFullWhileLocked(); 412 void SetDisabledWhileLocked(); 413 414 TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, 415 OptionalAutoLock* lock); 416 417 void FlushInternal(const OutputCallback& cb, 418 bool use_worker_thread, 419 bool discard_events); 420 421 // |generation| is used in the following callbacks to check if the callback 422 // is called for the flush of the current |logged_events_|. 423 void FlushCurrentThread(int generation, bool discard_events); 424 // Usually it runs on a different thread. 425 static void ConvertTraceEventsToTraceFormat( 426 std::unique_ptr<TraceBuffer> logged_events, 427 const TraceLog::OutputCallback& flush_output_callback, 428 const ArgumentFilterPredicate& argument_filter_predicate); 429 void FinishFlush(int generation, bool discard_events); 430 void OnFlushTimeout(int generation, bool discard_events); 431 432 int generation() const { 433 return static_cast<int>(subtle::NoBarrier_Load(&generation_)); 434 } 435 bool CheckGeneration(int generation) const { 436 return generation == this->generation(); 437 } 438 void UseNextTraceBuffer(); 439 440 TimeTicks OffsetNow() const { return OffsetTimestamp(TimeTicks::Now()); } 441 TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const { 442 return timestamp - time_offset_; 443 } 444 445 // Internal representation of trace options since we store the currently used 446 // trace option as an AtomicWord. 447 static const InternalTraceOptions kInternalNone; 448 static const InternalTraceOptions kInternalRecordUntilFull; 449 static const InternalTraceOptions kInternalRecordContinuously; 450 static const InternalTraceOptions kInternalEchoToConsole; 451 static const InternalTraceOptions kInternalEnableSampling; 452 static const InternalTraceOptions kInternalRecordAsMuchAsPossible; 453 static const InternalTraceOptions kInternalEnableArgumentFilter; 454 455 // This lock protects TraceLog member accesses (except for members protected 456 // by thread_info_lock_) from arbitrary threads. 457 mutable Lock lock_; 458 // This lock protects accesses to thread_names_, thread_event_start_times_ 459 // and thread_colors_. 460 Lock thread_info_lock_; 461 Mode mode_; 462 int num_traces_recorded_; 463 std::unique_ptr<TraceBuffer> logged_events_; 464 std::vector<std::unique_ptr<TraceEvent>> metadata_events_; 465 subtle::AtomicWord /* EventCallback */ event_callback_; 466 bool dispatching_to_observer_list_; 467 std::vector<EnabledStateObserver*> enabled_state_observer_list_; 468 std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> 469 async_observers_; 470 471 std::string process_name_; 472 base::hash_map<int, std::string> process_labels_; 473 int process_sort_index_; 474 base::hash_map<int, int> thread_sort_indices_; 475 base::hash_map<int, std::string> thread_names_; 476 477 // The following two maps are used only when ECHO_TO_CONSOLE. 478 base::hash_map<int, std::stack<TimeTicks>> thread_event_start_times_; 479 base::hash_map<std::string, int> thread_colors_; 480 481 TimeTicks buffer_limit_reached_timestamp_; 482 483 // XORed with TraceID to make it unlikely to collide with other processes. 484 unsigned long long process_id_hash_; 485 486 int process_id_; 487 488 TimeDelta time_offset_; 489 490 // Allow tests to wake up when certain events occur. 491 WatchEventCallback watch_event_callback_; 492 subtle::AtomicWord /* const unsigned char* */ watch_category_; 493 std::string watch_event_name_; 494 495 subtle::AtomicWord /* Options */ trace_options_; 496 497 // Sampling thread handles. 498 std::unique_ptr<TraceSamplingThread> sampling_thread_; 499 PlatformThreadHandle sampling_thread_handle_; 500 501 TraceConfig trace_config_; 502 TraceConfig event_callback_trace_config_; 503 504 ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_; 505 ThreadLocalBoolean thread_blocks_message_loop_; 506 ThreadLocalBoolean thread_is_in_trace_event_; 507 508 // Contains the message loops of threads that have had at least one event 509 // added into the local event buffer. Not using SingleThreadTaskRunner 510 // because we need to know the life time of the message loops. 511 hash_set<MessageLoop*> thread_message_loops_; 512 513 // For events which can't be added into the thread local buffer, e.g. events 514 // from threads without a message loop. 515 std::unique_ptr<TraceBufferChunk> thread_shared_chunk_; 516 size_t thread_shared_chunk_index_; 517 518 // Set when asynchronous Flush is in progress. 519 OutputCallback flush_output_callback_; 520 scoped_refptr<SingleThreadTaskRunner> flush_task_runner_; 521 ArgumentFilterPredicate argument_filter_predicate_; 522 subtle::AtomicWord generation_; 523 bool use_worker_thread_; 524 525 DISALLOW_COPY_AND_ASSIGN(TraceLog); 526 }; 527 528 } // namespace trace_event 529 } // namespace base 530 531 #endif // BASE_TRACE_EVENT_TRACE_LOG_H_ 532