• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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