| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 | |
| 6 #ifndef BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ | |
| 7 #define BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ | |
| 8 | |
| 9 #include <stack> | |
| 10 #include <string> | |
| 11 #include <vector> | |
| 12 | |
| 13 #include "base/atomicops.h" | |
| 14 #include "base/base_export.h" | |
| 15 #include "base/callback.h" | |
| 16 #include "base/containers/hash_tables.h" | |
| 17 #include "base/gtest_prod_util.h" | |
| 18 #include "base/memory/ref_counted_memory.h" | |
| 19 #include "base/memory/scoped_vector.h" | |
| 20 #include "base/observer_list.h" | |
| 21 #include "base/single_thread_task_runner.h" | |
| 22 #include "base/strings/string_util.h" | |
| 23 #include "base/synchronization/condition_variable.h" | |
| 24 #include "base/synchronization/lock.h" | |
| 25 #include "base/threading/thread.h" | |
| 26 #include "base/threading/thread_local.h" | |
| 27 #include "base/trace_event/memory_dump_provider.h" | |
| 28 #include "base/trace_event/trace_config.h" | |
| 29 #include "base/trace_event/trace_event_memory_overhead.h" | |
| 30 | |
| 31 // Older style trace macros with explicit id and extra data | |
| 32 // Only these macros result in publishing data to ETW as currently implemented. | |
| 33 // TODO(georgesak): Update/replace these with new ETW macros. | |
| 34 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ | |
| 35 base::trace_event::TraceLog::AddTraceEventEtw( \ | |
| 36 TRACE_EVENT_PHASE_BEGIN, \ | |
| 37 name, reinterpret_cast<const void*>(id), extra) | |
| 38 | |
| 39 #define TRACE_EVENT_END_ETW(name, id, extra) \ | |
| 40 base::trace_event::TraceLog::AddTraceEventEtw( \ | |
| 41 TRACE_EVENT_PHASE_END, \ | |
| 42 name, reinterpret_cast<const void*>(id), extra) | |
| 43 | |
| 44 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ | |
| 45 base::trace_event::TraceLog::AddTraceEventEtw( \ | |
| 46 TRACE_EVENT_PHASE_INSTANT, \ | |
| 47 name, reinterpret_cast<const void*>(id), extra) | |
| 48 | |
| 49 template <typename Type> | |
| 50 struct DefaultSingletonTraits; | |
| 51 | |
| 52 namespace base { | |
| 53 | |
| 54 class WaitableEvent; | |
| 55 class MessageLoop; | |
| 56 | |
| 57 namespace trace_event { | |
| 58 | |
| 59 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided | |
| 60 // class must implement this interface. | |
| 61 class BASE_EXPORT ConvertableToTraceFormat | |
| 62 : public RefCounted<ConvertableToTraceFormat> { | |
| 63 public: | |
| 64 // Append the class info to the provided |out| string. The appended | |
| 65 // data must be a valid JSON object. Strings must be properly quoted, and | |
| 66 // escaped. There is no processing applied to the content after it is | |
| 67 // appended. | |
| 68 virtual void AppendAsTraceFormat(std::string* out) const = 0; | |
| 69 | |
| 70 virtual void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); | |
| 71 | |
| 72 std::string ToString() const { | |
| 73 std::string result; | |
| 74 AppendAsTraceFormat(&result); | |
| 75 return result; | |
| 76 } | |
| 77 | |
| 78 protected: | |
| 79 virtual ~ConvertableToTraceFormat() {} | |
| 80 | |
| 81 private: | |
| 82 friend class RefCounted<ConvertableToTraceFormat>; | |
| 83 }; | |
| 84 | |
| 85 struct TraceEventHandle { | |
| 86 uint32 chunk_seq; | |
| 87 uint16 chunk_index; | |
| 88 uint16 event_index; | |
| 89 }; | |
| 90 | |
| 91 const int kTraceMaxNumArgs = 2; | |
| 92 | |
| 93 class BASE_EXPORT TraceEvent { | |
| 94 public: | |
| 95 union TraceValue { | |
| 96 bool as_bool; | |
| 97 unsigned long long as_uint; | |
| 98 long long as_int; | |
| 99 double as_double; | |
| 100 const void* as_pointer; | |
| 101 const char* as_string; | |
| 102 }; | |
| 103 | |
| 104 TraceEvent(); | |
| 105 ~TraceEvent(); | |
| 106 | |
| 107 // We don't need to copy TraceEvent except when TraceEventBuffer is cloned. | |
| 108 // Use explicit copy method to avoid accidentally misuse of copy. | |
| 109 void CopyFrom(const TraceEvent& other); | |
| 110 | |
| 111 void Initialize( | |
| 112 int thread_id, | |
| 113 TraceTicks timestamp, | |
| 114 ThreadTicks thread_timestamp, | |
| 115 char phase, | |
| 116 const unsigned char* category_group_enabled, | |
| 117 const char* name, | |
| 118 unsigned long long id, | |
| 119 int num_args, | |
| 120 const char** arg_names, | |
| 121 const unsigned char* arg_types, | |
| 122 const unsigned long long* arg_values, | |
| 123 const scoped_refptr<ConvertableToTraceFormat>* convertable_values, | |
| 124 unsigned int flags); | |
| 125 | |
| 126 void Reset(); | |
| 127 | |
| 128 void UpdateDuration(const TraceTicks& now, const ThreadTicks& thread_now); | |
| 129 | |
| 130 void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead*); | |
| 131 | |
| 132 // Serialize event data to JSON | |
| 133 typedef base::Callback<bool(const char* category_group_name, | |
| 134 const char* event_name)> ArgumentFilterPredicate; | |
| 135 void AppendAsJSON( | |
| 136 std::string* out, | |
| 137 const ArgumentFilterPredicate& argument_filter_predicate) const; | |
| 138 void AppendPrettyPrinted(std::ostringstream* out) const; | |
| 139 | |
| 140 static void AppendValueAsJSON(unsigned char type, | |
| 141 TraceValue value, | |
| 142 std::string* out); | |
| 143 | |
| 144 TraceTicks timestamp() const { return timestamp_; } | |
| 145 ThreadTicks thread_timestamp() const { return thread_timestamp_; } | |
| 146 char phase() const { return phase_; } | |
| 147 int thread_id() const { return thread_id_; } | |
| 148 TimeDelta duration() const { return duration_; } | |
| 149 TimeDelta thread_duration() const { return thread_duration_; } | |
| 150 unsigned long long id() const { return id_; } | |
| 151 unsigned int flags() const { return flags_; } | |
| 152 | |
| 153 // Exposed for unittesting: | |
| 154 | |
| 155 const base::RefCountedString* parameter_copy_storage() const { | |
| 156 return parameter_copy_storage_.get(); | |
| 157 } | |
| 158 | |
| 159 const unsigned char* category_group_enabled() const { | |
| 160 return category_group_enabled_; | |
| 161 } | |
| 162 | |
| 163 const char* name() const { return name_; } | |
| 164 | |
| 165 #if defined(OS_ANDROID) | |
| 166 void SendToATrace(); | |
| 167 #endif | |
| 168 | |
| 169 private: | |
| 170 // Note: these are ordered by size (largest first) for optimal packing. | |
| 171 TraceTicks timestamp_; | |
| 172 ThreadTicks thread_timestamp_; | |
| 173 TimeDelta duration_; | |
| 174 TimeDelta thread_duration_; | |
| 175 // id_ can be used to store phase-specific data. | |
| 176 unsigned long long id_; | |
| 177 scoped_ptr<TraceEventMemoryOverhead> cached_memory_overhead_estimate_; | |
| 178 TraceValue arg_values_[kTraceMaxNumArgs]; | |
| 179 const char* arg_names_[kTraceMaxNumArgs]; | |
| 180 scoped_refptr<ConvertableToTraceFormat> convertable_values_[kTraceMaxNumArgs]; | |
| 181 const unsigned char* category_group_enabled_; | |
| 182 const char* name_; | |
| 183 scoped_refptr<base::RefCountedString> parameter_copy_storage_; | |
| 184 int thread_id_; | |
| 185 char phase_; | |
| 186 unsigned int flags_; | |
| 187 unsigned char arg_types_[kTraceMaxNumArgs]; | |
| 188 | |
| 189 DISALLOW_COPY_AND_ASSIGN(TraceEvent); | |
| 190 }; | |
| 191 | |
| 192 // TraceBufferChunk is the basic unit of TraceBuffer. | |
| 193 class BASE_EXPORT TraceBufferChunk { | |
| 194 public: | |
| 195 explicit TraceBufferChunk(uint32 seq); | |
| 196 ~TraceBufferChunk(); | |
| 197 | |
| 198 void Reset(uint32 new_seq); | |
| 199 TraceEvent* AddTraceEvent(size_t* event_index); | |
| 200 bool IsFull() const { return next_free_ == kTraceBufferChunkSize; } | |
| 201 | |
| 202 uint32 seq() const { return seq_; } | |
| 203 size_t capacity() const { return kTraceBufferChunkSize; } | |
| 204 size_t size() const { return next_free_; } | |
| 205 | |
| 206 TraceEvent* GetEventAt(size_t index) { | |
| 207 DCHECK(index < size()); | |
| 208 return &chunk_[index]; | |
| 209 } | |
| 210 const TraceEvent* GetEventAt(size_t index) const { | |
| 211 DCHECK(index < size()); | |
| 212 return &chunk_[index]; | |
| 213 } | |
| 214 | |
| 215 scoped_ptr<TraceBufferChunk> Clone() const; | |
| 216 | |
| 217 void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); | |
| 218 | |
| 219 static const size_t kTraceBufferChunkSize = 64; | |
| 220 | |
| 221 private: | |
| 222 size_t next_free_; | |
| 223 scoped_ptr<TraceEventMemoryOverhead> cached_overhead_estimate_when_full_; | |
| 224 TraceEvent chunk_[kTraceBufferChunkSize]; | |
| 225 uint32 seq_; | |
| 226 }; | |
| 227 | |
| 228 // TraceBuffer holds the events as they are collected. | |
| 229 class BASE_EXPORT TraceBuffer { | |
| 230 public: | |
| 231 virtual ~TraceBuffer() {} | |
| 232 | |
| 233 virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t *index) = 0; | |
| 234 virtual void ReturnChunk(size_t index, | |
| 235 scoped_ptr<TraceBufferChunk> chunk) = 0; | |
| 236 | |
| 237 virtual bool IsFull() const = 0; | |
| 238 virtual size_t Size() const = 0; | |
| 239 virtual size_t Capacity() const = 0; | |
| 240 virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) = 0; | |
| 241 | |
| 242 // For iteration. Each TraceBuffer can only be iterated once. | |
| 243 virtual const TraceBufferChunk* NextChunk() = 0; | |
| 244 | |
| 245 virtual scoped_ptr<TraceBuffer> CloneForIteration() const = 0; | |
| 246 | |
| 247 // Computes an estimate of the size of the buffer, including all the retained | |
| 248 // objects. | |
| 249 virtual void EstimateTraceMemoryOverhead( | |
| 250 TraceEventMemoryOverhead* overhead) = 0; | |
| 251 }; | |
| 252 | |
| 253 // TraceResultBuffer collects and converts trace fragments returned by TraceLog | |
| 254 // to JSON output. | |
| 255 class BASE_EXPORT TraceResultBuffer { | |
| 256 public: | |
| 257 typedef base::Callback<void(const std::string&)> OutputCallback; | |
| 258 | |
| 259 // If you don't need to stream JSON chunks out efficiently, and just want to | |
| 260 // get a complete JSON string after calling Finish, use this struct to collect | |
| 261 // JSON trace output. | |
| 262 struct BASE_EXPORT SimpleOutput { | |
| 263 OutputCallback GetCallback(); | |
| 264 void Append(const std::string& json_string); | |
| 265 | |
| 266 // Do what you want with the json_output_ string after calling | |
| 267 // TraceResultBuffer::Finish. | |
| 268 std::string json_output; | |
| 269 }; | |
| 270 | |
| 271 TraceResultBuffer(); | |
| 272 ~TraceResultBuffer(); | |
| 273 | |
| 274 // Set callback. The callback will be called during Start with the initial | |
| 275 // JSON output and during AddFragment and Finish with following JSON output | |
| 276 // chunks. The callback target must live past the last calls to | |
| 277 // TraceResultBuffer::Start/AddFragment/Finish. | |
| 278 void SetOutputCallback(const OutputCallback& json_chunk_callback); | |
| 279 | |
| 280 // Start JSON output. This resets all internal state, so you can reuse | |
| 281 // the TraceResultBuffer by calling Start. | |
| 282 void Start(); | |
| 283 | |
| 284 // Call AddFragment 0 or more times to add trace fragments from TraceLog. | |
| 285 void AddFragment(const std::string& trace_fragment); | |
| 286 | |
| 287 // When all fragments have been added, call Finish to complete the JSON | |
| 288 // formatted output. | |
| 289 void Finish(); | |
| 290 | |
| 291 private: | |
| 292 OutputCallback output_callback_; | |
| 293 bool append_comma_; | |
| 294 }; | |
| 295 | |
| 296 class TraceSamplingThread; | |
| 297 | |
| 298 struct BASE_EXPORT TraceLogStatus { | |
| 299 TraceLogStatus(); | |
| 300 ~TraceLogStatus(); | |
| 301 size_t event_capacity; | |
| 302 size_t event_count; | |
| 303 }; | |
| 304 | |
| 305 class BASE_EXPORT TraceLog : public MemoryDumpProvider { | |
| 306 public: | |
| 307 enum Mode { | |
| 308 DISABLED = 0, | |
| 309 RECORDING_MODE, | |
| 310 MONITORING_MODE, | |
| 311 }; | |
| 312 | |
| 313 // The pointer returned from GetCategoryGroupEnabledInternal() points to a | |
| 314 // value with zero or more of the following bits. Used in this class only. | |
| 315 // The TRACE_EVENT macros should only use the value as a bool. | |
| 316 // These values must be in sync with macro values in TraceEvent.h in Blink. | |
| 317 enum CategoryGroupEnabledFlags { | |
| 318 // Category group enabled for the recording mode. | |
| 319 ENABLED_FOR_RECORDING = 1 << 0, | |
| 320 // Category group enabled for the monitoring mode. | |
| 321 ENABLED_FOR_MONITORING = 1 << 1, | |
| 322 // Category group enabled by SetEventCallbackEnabled(). | |
| 323 ENABLED_FOR_EVENT_CALLBACK = 1 << 2, | |
| 324 // Category group enabled to export events to ETW. | |
| 325 ENABLED_FOR_ETW_EXPORT = 1 << 3 | |
| 326 }; | |
| 327 | |
| 328 static TraceLog* GetInstance(); | |
| 329 | |
| 330 // Get set of known category groups. This can change as new code paths are | |
| 331 // reached. The known category groups are inserted into |category_groups|. | |
| 332 void GetKnownCategoryGroups(std::vector<std::string>* category_groups); | |
| 333 | |
| 334 // Retrieves a copy (for thread-safety) of the current TraceConfig. | |
| 335 TraceConfig GetCurrentTraceConfig() const; | |
| 336 | |
| 337 // Initializes the thread-local event buffer, if not already initialized and | |
| 338 // if the current thread supports that (has a message loop). | |
| 339 void InitializeThreadLocalEventBufferIfSupported(); | |
| 340 | |
| 341 // Enables normal tracing (recording trace events in the trace buffer). | |
| 342 // See TraceConfig comments for details on how to control what categories | |
| 343 // will be traced. If tracing has already been enabled, |category_filter| will | |
| 344 // be merged into the current category filter. | |
| 345 void SetEnabled(const TraceConfig& trace_config, Mode mode); | |
| 346 | |
| 347 // Disables normal tracing for all categories. | |
| 348 void SetDisabled(); | |
| 349 | |
| 350 bool IsEnabled() { return mode_ != DISABLED; } | |
| 351 | |
| 352 // The number of times we have begun recording traces. If tracing is off, | |
| 353 // returns -1. If tracing is on, then it returns the number of times we have | |
| 354 // recorded a trace. By watching for this number to increment, you can | |
| 355 // passively discover when a new trace has begun. This is then used to | |
| 356 // implement the TRACE_EVENT_IS_NEW_TRACE() primitive. | |
| 357 int GetNumTracesRecorded(); | |
| 358 | |
| 359 #if defined(OS_ANDROID) | |
| 360 void StartATrace(); | |
| 361 void StopATrace(); | |
| 362 void AddClockSyncMetadataEvent(); | |
| 363 #endif | |
| 364 | |
| 365 // Enabled state listeners give a callback when tracing is enabled or | |
| 366 // disabled. This can be used to tie into other library's tracing systems | |
| 367 // on-demand. | |
| 368 class BASE_EXPORT EnabledStateObserver { | |
| 369 public: | |
| 370 virtual ~EnabledStateObserver() = default; | |
| 371 | |
| 372 // Called just after the tracing system becomes enabled, outside of the | |
| 373 // |lock_|. TraceLog::IsEnabled() is true at this point. | |
| 374 virtual void OnTraceLogEnabled() = 0; | |
| 375 | |
| 376 // Called just after the tracing system disables, outside of the |lock_|. | |
| 377 // TraceLog::IsEnabled() is false at this point. | |
| 378 virtual void OnTraceLogDisabled() = 0; | |
| 379 }; | |
| 380 void AddEnabledStateObserver(EnabledStateObserver* listener); | |
| 381 void RemoveEnabledStateObserver(EnabledStateObserver* listener); | |
| 382 bool HasEnabledStateObserver(EnabledStateObserver* listener) const; | |
| 383 | |
| 384 TraceLogStatus GetStatus() const; | |
| 385 bool BufferIsFull() const; | |
| 386 | |
| 387 // Computes an estimate of the size of the TraceLog including all the retained | |
| 388 // objects. | |
| 389 void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); | |
| 390 | |
| 391 // Not using base::Callback because of its limited by 7 parameters. | |
| 392 // Also, using primitive type allows directly passing callback from WebCore. | |
| 393 // WARNING: It is possible for the previously set callback to be called | |
| 394 // after a call to SetEventCallbackEnabled() that replaces or a call to | |
| 395 // SetEventCallbackDisabled() that disables the callback. | |
| 396 // This callback may be invoked on any thread. | |
| 397 // For TRACE_EVENT_PHASE_COMPLETE events, the client will still receive pairs | |
| 398 // of TRACE_EVENT_PHASE_BEGIN and TRACE_EVENT_PHASE_END events to keep the | |
| 399 // interface simple. | |
| 400 typedef void (*EventCallback)(TraceTicks timestamp, | |
| 401 char phase, | |
| 402 const unsigned char* category_group_enabled, | |
| 403 const char* name, | |
| 404 unsigned long long id, | |
| 405 int num_args, | |
| 406 const char* const arg_names[], | |
| 407 const unsigned char arg_types[], | |
| 408 const unsigned long long arg_values[], | |
| 409 unsigned int flags); | |
| 410 | |
| 411 // Enable tracing for EventCallback. | |
| 412 void SetEventCallbackEnabled(const TraceConfig& trace_config, | |
| 413 EventCallback cb); | |
| 414 void SetEventCallbackDisabled(); | |
| 415 void SetArgumentFilterPredicate( | |
| 416 const TraceEvent::ArgumentFilterPredicate& argument_filter_predicate); | |
| 417 | |
| 418 // Flush all collected events to the given output callback. The callback will | |
| 419 // be called one or more times either synchronously or asynchronously from | |
| 420 // the current thread with IPC-bite-size chunks. The string format is | |
| 421 // undefined. Use TraceResultBuffer to convert one or more trace strings to | |
| 422 // JSON. The callback can be null if the caller doesn't want any data. | |
| 423 // Due to the implementation of thread-local buffers, flush can't be | |
| 424 // done when tracing is enabled. If called when tracing is enabled, the | |
| 425 // callback will be called directly with (empty_string, false) to indicate | |
| 426 // the end of this unsuccessful flush. Flush does the serialization | |
| 427 // on the same thread if the caller doesn't set use_worker_thread explicitly. | |
| 428 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&, | |
| 429 bool has_more_events)> OutputCallback; | |
| 430 void Flush(const OutputCallback& cb, bool use_worker_thread = false); | |
| 431 void FlushButLeaveBufferIntact(const OutputCallback& flush_output_callback); | |
| 432 | |
| 433 // Cancels tracing and discards collected data. | |
| 434 void CancelTracing(const OutputCallback& cb); | |
| 435 | |
| 436 // Called by TRACE_EVENT* macros, don't call this directly. | |
| 437 // The name parameter is a category group for example: | |
| 438 // TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent") | |
| 439 static const unsigned char* GetCategoryGroupEnabled(const char* name); | |
| 440 static const char* GetCategoryGroupName( | |
| 441 const unsigned char* category_group_enabled); | |
| 442 | |
| 443 // Called by TRACE_EVENT* macros, don't call this directly. | |
| 444 // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied | |
| 445 // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. | |
| 446 TraceEventHandle AddTraceEvent( | |
| 447 char phase, | |
| 448 const unsigned char* category_group_enabled, | |
| 449 const char* name, | |
| 450 unsigned long long id, | |
| 451 int num_args, | |
| 452 const char** arg_names, | |
| 453 const unsigned char* arg_types, | |
| 454 const unsigned long long* arg_values, | |
| 455 const scoped_refptr<ConvertableToTraceFormat>* convertable_values, | |
| 456 unsigned int flags); | |
| 457 TraceEventHandle AddTraceEventWithThreadIdAndTimestamp( | |
| 458 char phase, | |
| 459 const unsigned char* category_group_enabled, | |
| 460 const char* name, | |
| 461 unsigned long long id, | |
| 462 int thread_id, | |
| 463 const TraceTicks& timestamp, | |
| 464 int num_args, | |
| 465 const char** arg_names, | |
| 466 const unsigned char* arg_types, | |
| 467 const unsigned long long* arg_values, | |
| 468 const scoped_refptr<ConvertableToTraceFormat>* convertable_values, | |
| 469 unsigned int flags); | |
| 470 static void AddTraceEventEtw(char phase, | |
| 471 const char* category_group, | |
| 472 const void* id, | |
| 473 const char* extra); | |
| 474 static void AddTraceEventEtw(char phase, | |
| 475 const char* category_group, | |
| 476 const void* id, | |
| 477 const std::string& extra); | |
| 478 | |
| 479 void UpdateTraceEventDuration(const unsigned char* category_group_enabled, | |
| 480 const char* name, | |
| 481 TraceEventHandle handle); | |
| 482 | |
| 483 // For every matching event, the callback will be called. | |
| 484 typedef base::Callback<void()> WatchEventCallback; | |
| 485 void SetWatchEvent(const std::string& category_name, | |
| 486 const std::string& event_name, | |
| 487 const WatchEventCallback& callback); | |
| 488 // Cancel the watch event. If tracing is enabled, this may race with the | |
| 489 // watch event notification firing. | |
| 490 void CancelWatchEvent(); | |
| 491 | |
| 492 int process_id() const { return process_id_; } | |
| 493 | |
| 494 uint64 MangleEventId(uint64 id); | |
| 495 | |
| 496 // Exposed for unittesting: | |
| 497 | |
| 498 void WaitSamplingEventForTesting(); | |
| 499 | |
| 500 // Allows deleting our singleton instance. | |
| 501 static void DeleteForTesting(); | |
| 502 | |
| 503 // Allow tests to inspect TraceEvents. | |
| 504 TraceEvent* GetEventByHandle(TraceEventHandle handle); | |
| 505 | |
| 506 void SetProcessID(int process_id); | |
| 507 | |
| 508 // Process sort indices, if set, override the order of a process will appear | |
| 509 // relative to other processes in the trace viewer. Processes are sorted first | |
| 510 // on their sort index, ascending, then by their name, and then tid. | |
| 511 void SetProcessSortIndex(int sort_index); | |
| 512 | |
| 513 // Sets the name of the process. | |
| 514 void SetProcessName(const std::string& process_name); | |
| 515 | |
| 516 // Processes can have labels in addition to their names. Use labels, for | |
| 517 // instance, to list out the web page titles that a process is handling. | |
| 518 void UpdateProcessLabel(int label_id, const std::string& current_label); | |
| 519 void RemoveProcessLabel(int label_id); | |
| 520 | |
| 521 // Thread sort indices, if set, override the order of a thread will appear | |
| 522 // within its process in the trace viewer. Threads are sorted first on their | |
| 523 // sort index, ascending, then by their name, and then tid. | |
| 524 void SetThreadSortIndex(PlatformThreadId , int sort_index); | |
| 525 | |
| 526 // Allow setting an offset between the current TraceTicks time and the time | |
| 527 // that should be reported. | |
| 528 void SetTimeOffset(TimeDelta offset); | |
| 529 | |
| 530 size_t GetObserverCountForTest() const; | |
| 531 | |
| 532 // Call this method if the current thread may block the message loop to | |
| 533 // prevent the thread from using the thread-local buffer because the thread | |
| 534 // may not handle the flush request in time causing lost of unflushed events. | |
| 535 void SetCurrentThreadBlocksMessageLoop(); | |
| 536 | |
| 537 private: | |
| 538 typedef unsigned int InternalTraceOptions; | |
| 539 | |
| 540 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | |
| 541 TraceBufferRingBufferGetReturnChunk); | |
| 542 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | |
| 543 TraceBufferRingBufferHalfIteration); | |
| 544 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | |
| 545 TraceBufferRingBufferFullIteration); | |
| 546 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | |
| 547 TraceBufferVectorReportFull); | |
| 548 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | |
| 549 ConvertTraceConfigToInternalOptions); | |
| 550 FRIEND_TEST_ALL_PREFIXES(TraceEventTestFixture, | |
| 551 TraceRecordAsMuchAsPossibleMode); | |
| 552 | |
| 553 // This allows constructor and destructor to be private and usable only | |
| 554 // by the Singleton class. | |
| 555 friend struct DefaultSingletonTraits<TraceLog>; | |
| 556 | |
| 557 // MemoryDumpProvider implementation. | |
| 558 bool OnMemoryDump(ProcessMemoryDump* pmd) override; | |
| 559 | |
| 560 // Enable/disable each category group based on the current mode_, | |
| 561 // category_filter_, event_callback_ and event_callback_category_filter_. | |
| 562 // Enable the category group in the enabled mode if category_filter_ matches | |
| 563 // the category group, or event_callback_ is not null and | |
| 564 // event_callback_category_filter_ matches the category group. | |
| 565 void UpdateCategoryGroupEnabledFlags(); | |
| 566 void UpdateCategoryGroupEnabledFlag(size_t category_index); | |
| 567 | |
| 568 // Configure synthetic delays based on the values set in the current | |
| 569 // trace config. | |
| 570 void UpdateSyntheticDelaysFromTraceConfig(); | |
| 571 | |
| 572 InternalTraceOptions GetInternalOptionsFromTraceConfig( | |
| 573 const TraceConfig& config); | |
| 574 | |
| 575 class ThreadLocalEventBuffer; | |
| 576 class OptionalAutoLock; | |
| 577 | |
| 578 TraceLog(); | |
| 579 ~TraceLog() override; | |
| 580 const unsigned char* GetCategoryGroupEnabledInternal(const char* name); | |
| 581 void AddMetadataEventsWhileLocked(); | |
| 582 | |
| 583 InternalTraceOptions trace_options() const { | |
| 584 return static_cast<InternalTraceOptions>( | |
| 585 subtle::NoBarrier_Load(&trace_options_)); | |
| 586 } | |
| 587 | |
| 588 TraceBuffer* trace_buffer() const { return logged_events_.get(); } | |
| 589 TraceBuffer* CreateTraceBuffer(); | |
| 590 TraceBuffer* CreateTraceBufferVectorOfSize(size_t max_chunks); | |
| 591 | |
| 592 std::string EventToConsoleMessage(unsigned char phase, | |
| 593 const TraceTicks& timestamp, | |
| 594 TraceEvent* trace_event); | |
| 595 | |
| 596 TraceEvent* AddEventToThreadSharedChunkWhileLocked(TraceEventHandle* handle, | |
| 597 bool check_buffer_is_full); | |
| 598 void CheckIfBufferIsFullWhileLocked(); | |
| 599 void SetDisabledWhileLocked(); | |
| 600 | |
| 601 TraceEvent* GetEventByHandleInternal(TraceEventHandle handle, | |
| 602 OptionalAutoLock* lock); | |
| 603 | |
| 604 void FlushInternal(const OutputCallback& cb, | |
| 605 bool use_worker_thread, | |
| 606 bool discard_events); | |
| 607 | |
| 608 // |generation| is used in the following callbacks to check if the callback | |
| 609 // is called for the flush of the current |logged_events_|. | |
| 610 void FlushCurrentThread(int generation, bool discard_events); | |
| 611 // Usually it runs on a different thread. | |
| 612 static void ConvertTraceEventsToTraceFormat( | |
| 613 scoped_ptr<TraceBuffer> logged_events, | |
| 614 const TraceLog::OutputCallback& flush_output_callback, | |
| 615 const TraceEvent::ArgumentFilterPredicate& argument_filter_predicate); | |
| 616 void FinishFlush(int generation, bool discard_events); | |
| 617 void OnFlushTimeout(int generation, bool discard_events); | |
| 618 | |
| 619 int generation() const { | |
| 620 return static_cast<int>(subtle::NoBarrier_Load(&generation_)); | |
| 621 } | |
| 622 bool CheckGeneration(int generation) const { | |
| 623 return generation == this->generation(); | |
| 624 } | |
| 625 void UseNextTraceBuffer(); | |
| 626 | |
| 627 TraceTicks OffsetNow() const { | |
| 628 return OffsetTimestamp(TraceTicks::Now()); | |
| 629 } | |
| 630 TraceTicks OffsetTimestamp(const TraceTicks& timestamp) const { | |
| 631 return timestamp - time_offset_; | |
| 632 } | |
| 633 | |
| 634 // Internal representation of trace options since we store the currently used | |
| 635 // trace option as an AtomicWord. | |
| 636 static const InternalTraceOptions kInternalNone; | |
| 637 static const InternalTraceOptions kInternalRecordUntilFull; | |
| 638 static const InternalTraceOptions kInternalRecordContinuously; | |
| 639 static const InternalTraceOptions kInternalEchoToConsole; | |
| 640 static const InternalTraceOptions kInternalEnableSampling; | |
| 641 static const InternalTraceOptions kInternalRecordAsMuchAsPossible; | |
| 642 static const InternalTraceOptions kInternalEnableArgumentFilter; | |
| 643 | |
| 644 // This lock protects TraceLog member accesses (except for members protected | |
| 645 // by thread_info_lock_) from arbitrary threads. | |
| 646 mutable Lock lock_; | |
| 647 // This lock protects accesses to thread_names_, thread_event_start_times_ | |
| 648 // and thread_colors_. | |
| 649 Lock thread_info_lock_; | |
| 650 Mode mode_; | |
| 651 int num_traces_recorded_; | |
| 652 scoped_ptr<TraceBuffer> logged_events_; | |
| 653 subtle::AtomicWord /* EventCallback */ event_callback_; | |
| 654 bool dispatching_to_observer_list_; | |
| 655 std::vector<EnabledStateObserver*> enabled_state_observer_list_; | |
| 656 | |
| 657 std::string process_name_; | |
| 658 base::hash_map<int, std::string> process_labels_; | |
| 659 int process_sort_index_; | |
| 660 base::hash_map<int, int> thread_sort_indices_; | |
| 661 base::hash_map<int, std::string> thread_names_; | |
| 662 | |
| 663 // The following two maps are used only when ECHO_TO_CONSOLE. | |
| 664 base::hash_map<int, std::stack<TraceTicks> > thread_event_start_times_; | |
| 665 base::hash_map<std::string, int> thread_colors_; | |
| 666 | |
| 667 TraceTicks buffer_limit_reached_timestamp_; | |
| 668 | |
| 669 // XORed with TraceID to make it unlikely to collide with other processes. | |
| 670 unsigned long long process_id_hash_; | |
| 671 | |
| 672 int process_id_; | |
| 673 | |
| 674 TimeDelta time_offset_; | |
| 675 | |
| 676 // Allow tests to wake up when certain events occur. | |
| 677 WatchEventCallback watch_event_callback_; | |
| 678 subtle::AtomicWord /* const unsigned char* */ watch_category_; | |
| 679 std::string watch_event_name_; | |
| 680 | |
| 681 subtle::AtomicWord /* Options */ trace_options_; | |
| 682 | |
| 683 // Sampling thread handles. | |
| 684 scoped_ptr<TraceSamplingThread> sampling_thread_; | |
| 685 PlatformThreadHandle sampling_thread_handle_; | |
| 686 | |
| 687 TraceConfig trace_config_; | |
| 688 TraceConfig event_callback_trace_config_; | |
| 689 | |
| 690 ThreadLocalPointer<ThreadLocalEventBuffer> thread_local_event_buffer_; | |
| 691 ThreadLocalBoolean thread_blocks_message_loop_; | |
| 692 ThreadLocalBoolean thread_is_in_trace_event_; | |
| 693 | |
| 694 // Contains the message loops of threads that have had at least one event | |
| 695 // added into the local event buffer. Not using SingleThreadTaskRunner | |
| 696 // because we need to know the life time of the message loops. | |
| 697 hash_set<MessageLoop*> thread_message_loops_; | |
| 698 | |
| 699 // For events which can't be added into the thread local buffer, e.g. events | |
| 700 // from threads without a message loop. | |
| 701 scoped_ptr<TraceBufferChunk> thread_shared_chunk_; | |
| 702 size_t thread_shared_chunk_index_; | |
| 703 | |
| 704 // Set when asynchronous Flush is in progress. | |
| 705 OutputCallback flush_output_callback_; | |
| 706 scoped_refptr<SingleThreadTaskRunner> flush_task_runner_; | |
| 707 TraceEvent::ArgumentFilterPredicate argument_filter_predicate_; | |
| 708 subtle::AtomicWord generation_; | |
| 709 bool use_worker_thread_; | |
| 710 | |
| 711 DISALLOW_COPY_AND_ASSIGN(TraceLog); | |
| 712 }; | |
| 713 | |
| 714 } // namespace trace_event | |
| 715 } // namespace base | |
| 716 | |
| 717 #endif // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ | |
| OLD | NEW |