• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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_EVENT_H_
6 #define BASE_TRACE_EVENT_TRACE_EVENT_H_
7 
8 // This header file defines implementation details of how the trace macros in
9 // trace_event_common.h collect and store trace events. Anything not
10 // implementation-specific should go in trace_event_common.h instead of here.
11 
12 #include <stddef.h>
13 #include <stdint.h>
14 
15 #include <memory>
16 #include <utility>
17 
18 #include "base/atomicops.h"
19 #include "base/base_export.h"
20 #include "base/threading/platform_thread.h"
21 #include "base/time/time.h"
22 #include "base/time/time_override.h"
23 #include "base/trace_event/builtin_categories.h"
24 #include "base/trace_event/common/trace_event_common.h"  // IWYU pragma: export
25 #include "base/trace_event/trace_arguments.h"
26 #include "base/trace_event/trace_category.h"
27 #include "base/trace_event/trace_log.h"
28 #include "base/trace_event/traced_value_support.h"
29 #include "base/tracing_buildflags.h"
30 
31 // Legacy TRACE_EVENT_API entrypoints. Do not use from new code.
32 
33 // Add a trace event to the platform tracing system.
34 // base::trace_event::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT(
35 //                    char phase,
36 //                    const unsigned char* category_group_enabled,
37 //                    const char* name,
38 //                    const char* scope,
39 //                    uint64_t id,
40 //                    base::trace_event::TraceArguments* args,
41 //                    unsigned int flags)
42 #define TRACE_EVENT_API_ADD_TRACE_EVENT trace_event_internal::AddTraceEvent
43 
44 // Add a trace event to the platform tracing system.
45 // base::trace_event::TraceEventHandle
46 // TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID(
47 //                    char phase,
48 //                    const unsigned char* category_group_enabled,
49 //                    const char* name,
50 //                    const char* scope,
51 //                    uint64_t id,
52 //                    uint64_t bind_id,
53 //                    base::trace_event::TraceArguments* args,
54 //                    unsigned int flags)
55 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID \
56   trace_event_internal::AddTraceEventWithBindId
57 
58 // Add a trace event to the platform tracing system overriding the pid.
59 // The resulting event will have tid = pid == (process_id passed here).
60 // base::trace_event::TraceEventHandle
61 // TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID(
62 //                    char phase,
63 //                    const unsigned char* category_group_enabled,
64 //                    const char* name,
65 //                    const char* scope,
66 //                    uint64_t id,
67 //                    base::ProcessId process_id,
68 //                    base::trace_event::TraceArguments* args,
69 //                    unsigned int flags)
70 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID \
71   trace_event_internal::AddTraceEventWithProcessId
72 
73 // Add a trace event to the platform tracing system.
74 // base::trace_event::TraceEventHandle
75 // TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
76 //                    char phase,
77 //                    const unsigned char* category_group_enabled,
78 //                    const char* name,
79 //                    const char* scope,
80 //                    uint64_t id,
81 //                    uint64_t bind_id,
82 //                    base::PlatformThreadId thread_id,
83 //                    const TimeTicks& timestamp,
84 //                    base::trace_event::TraceArguments* args,
85 //                    unsigned int flags)
86 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP \
87   trace_event_internal::AddTraceEventWithThreadIdAndTimestamp
88 
89 // Set the duration field of a COMPLETE trace event.
90 // void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
91 //     const unsigned char* category_group_enabled,
92 //     const char* name,
93 //     base::trace_event::TraceEventHandle id)
94 #define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \
95   trace_event_internal::UpdateTraceEventDuration
96 
97 // Adds a metadata event to the trace log. The |AppendValueAsTraceFormat| method
98 // on the convertable value will be called at flush time.
99 // TRACE_EVENT_API_ADD_METADATA_EVENT(
100 //     const unsigned char* category_group_enabled,
101 //     const char* event_name,
102 //     const char* arg_name,
103 //     std::unique_ptr<ConvertableToTraceFormat> arg_value)
104 #define TRACE_EVENT_API_ADD_METADATA_EVENT \
105     trace_event_internal::AddMetadataEvent
106 
107 // Defines atomic operations used internally by the tracing system.
108 // Acquire/release barriers are important here: crbug.com/1330114#c8.
109 #define TRACE_EVENT_API_ATOMIC_WORD base::subtle::AtomicWord
110 #define TRACE_EVENT_API_ATOMIC_LOAD(var) base::subtle::Acquire_Load(&(var))
111 #define TRACE_EVENT_API_ATOMIC_STORE(var, value) \
112   base::subtle::Release_Store(&(var), (value))
113 
114 // Defines visibility for classes in trace_event.h
115 #define TRACE_EVENT_API_CLASS_EXPORT BASE_EXPORT
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 
119 namespace trace_event_internal {
120 
121 // Specify these values when the corresponding argument of AddTraceEvent is not
122 // used.
123 const int kZeroNumArgs = 0;
124 const std::nullptr_t kGlobalScope = nullptr;
125 const uint64_t kNoId = 0;
126 
127 // TraceID encapsulates an ID that can either be an integer or pointer.
128 class BASE_EXPORT TraceID {
129  public:
130   // Can be combined with WithScope.
131   class LocalId {
132    public:
LocalId(const void * raw_id)133     explicit LocalId(const void* raw_id)
134         : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {}
LocalId(uint64_t raw_id)135     explicit LocalId(uint64_t raw_id) : raw_id_(raw_id) {}
raw_id()136     uint64_t raw_id() const { return raw_id_; }
137 
138    private:
139     uint64_t raw_id_;
140   };
141 
142   // Can be combined with WithScope.
143   class GlobalId {
144    public:
GlobalId(uint64_t raw_id)145     explicit GlobalId(uint64_t raw_id) : raw_id_(raw_id) {}
raw_id()146     uint64_t raw_id() const { return raw_id_; }
147 
148    private:
149     uint64_t raw_id_;
150   };
151 
152   class WithScope {
153    public:
WithScope(const char * scope,uint64_t raw_id)154     WithScope(const char* scope, uint64_t raw_id)
155         : scope_(scope), raw_id_(raw_id) {}
WithScope(const char * scope,LocalId local_id)156     WithScope(const char* scope, LocalId local_id)
157         : scope_(scope), raw_id_(local_id.raw_id()) {
158       id_flags_ = TRACE_EVENT_FLAG_HAS_LOCAL_ID;
159     }
WithScope(const char * scope,GlobalId global_id)160     WithScope(const char* scope, GlobalId global_id)
161         : scope_(scope), raw_id_(global_id.raw_id()) {
162       id_flags_ = TRACE_EVENT_FLAG_HAS_GLOBAL_ID;
163     }
raw_id()164     uint64_t raw_id() const { return raw_id_; }
scope()165     const char* scope() const { return scope_; }
id_flags()166     unsigned int id_flags() const { return id_flags_; }
167 
168    private:
169     const char* scope_ = nullptr;
170     uint64_t raw_id_;
171     unsigned int id_flags_ = TRACE_EVENT_FLAG_HAS_ID;
172   };
173 
TraceID(const void * raw_id)174   explicit TraceID(const void* raw_id)
175       : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {
176     id_flags_ = TRACE_EVENT_FLAG_HAS_LOCAL_ID;
177   }
TraceID(unsigned long long raw_id)178   explicit TraceID(unsigned long long raw_id)
179       : raw_id_(static_cast<uint64_t>(raw_id)) {}
TraceID(unsigned long raw_id)180   explicit TraceID(unsigned long raw_id)
181       : raw_id_(static_cast<uint64_t>(raw_id)) {}
TraceID(unsigned int raw_id)182   explicit TraceID(unsigned int raw_id)
183       : raw_id_(static_cast<uint64_t>(raw_id)) {}
TraceID(unsigned short raw_id)184   explicit TraceID(unsigned short raw_id)
185       : raw_id_(static_cast<uint64_t>(raw_id)) {}
TraceID(unsigned char raw_id)186   explicit TraceID(unsigned char raw_id)
187       : raw_id_(static_cast<uint64_t>(raw_id)) {}
TraceID(long long raw_id)188   explicit TraceID(long long raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {}
TraceID(long raw_id)189   explicit TraceID(long raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {}
TraceID(int raw_id)190   explicit TraceID(int raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {}
TraceID(short raw_id)191   explicit TraceID(short raw_id) : raw_id_(static_cast<uint64_t>(raw_id)) {}
TraceID(signed char raw_id)192   explicit TraceID(signed char raw_id)
193       : raw_id_(static_cast<uint64_t>(raw_id)) {}
TraceID(LocalId raw_id)194   explicit TraceID(LocalId raw_id) : raw_id_(raw_id.raw_id()) {
195     id_flags_ = TRACE_EVENT_FLAG_HAS_LOCAL_ID;
196   }
TraceID(GlobalId raw_id)197   explicit TraceID(GlobalId raw_id) : raw_id_(raw_id.raw_id()) {
198     id_flags_ = TRACE_EVENT_FLAG_HAS_GLOBAL_ID;
199   }
TraceID(WithScope scoped_id)200   explicit TraceID(WithScope scoped_id)
201       : scope_(scoped_id.scope()),
202         raw_id_(scoped_id.raw_id()),
203         id_flags_(scoped_id.id_flags()) {}
204 
raw_id()205   uint64_t raw_id() const { return raw_id_; }
scope()206   const char* scope() const { return scope_; }
id_flags()207   unsigned int id_flags() const { return id_flags_; }
208 
209  private:
210   const char* scope_ = nullptr;
211   uint64_t raw_id_;
212   unsigned int id_flags_ = TRACE_EVENT_FLAG_HAS_ID;
213 };
214 
215 // These functions all internally call
216 // base::trace_event::TraceLog::GetInstance() then call the method with the same
217 // name on it. This is used to reduce the generated machine code at each
218 // TRACE_EVENTXXX macro call.
219 
220 base::trace_event::TraceEventHandle BASE_EXPORT
221 AddTraceEvent(char phase,
222               const unsigned char* category_group_enabled,
223               const char* name,
224               const char* scope,
225               uint64_t id,
226               base::trace_event::TraceArguments* args,
227               unsigned int flags);
228 
229 base::trace_event::TraceEventHandle BASE_EXPORT
230 AddTraceEventWithBindId(char phase,
231                         const unsigned char* category_group_enabled,
232                         const char* name,
233                         const char* scope,
234                         uint64_t id,
235                         uint64_t bind_id,
236                         base::trace_event::TraceArguments* args,
237                         unsigned int flags);
238 
239 base::trace_event::TraceEventHandle BASE_EXPORT
240 AddTraceEventWithProcessId(char phase,
241                            const unsigned char* category_group_enabled,
242                            const char* name,
243                            const char* scope,
244                            uint64_t id,
245                            base::ProcessId process_id,
246                            base::trace_event::TraceArguments* args,
247                            unsigned int flags);
248 
249 base::trace_event::TraceEventHandle BASE_EXPORT
250 AddTraceEventWithThreadIdAndTimestamp(
251     char phase,
252     const unsigned char* category_group_enabled,
253     const char* name,
254     const char* scope,
255     uint64_t id,
256     base::PlatformThreadId thread_id,
257     const base::TimeTicks& timestamp,
258     base::trace_event::TraceArguments* args,
259     unsigned int flags);
260 
261 base::trace_event::TraceEventHandle BASE_EXPORT
262 AddTraceEventWithThreadIdAndTimestamp(
263     char phase,
264     const unsigned char* category_group_enabled,
265     const char* name,
266     const char* scope,
267     uint64_t id,
268     uint64_t bind_id,
269     base::PlatformThreadId thread_id,
270     const base::TimeTicks& timestamp,
271     base::trace_event::TraceArguments* args,
272     unsigned int flags);
273 
274 base::trace_event::TraceEventHandle BASE_EXPORT
275 AddTraceEventWithThreadIdAndTimestamps(
276     char phase,
277     const unsigned char* category_group_enabled,
278     const char* name,
279     const char* scope,
280     uint64_t id,
281     base::PlatformThreadId thread_id,
282     const base::TimeTicks& timestamp,
283     const base::ThreadTicks& thread_timestamp,
284     unsigned int flags);
285 
286 void BASE_EXPORT AddMetadataEvent(const unsigned char* category_group_enabled,
287                                   const char* name,
288                                   base::trace_event::TraceArguments* args,
289                                   unsigned int flags);
290 
291 int BASE_EXPORT GetNumTracesRecorded();
292 
293 void BASE_EXPORT
294 UpdateTraceEventDuration(const unsigned char* category_group_enabled,
295                          const char* name,
296                          base::trace_event::TraceEventHandle handle);
297 
298 void BASE_EXPORT
299 UpdateTraceEventDurationExplicit(const unsigned char* category_group_enabled,
300                                  const char* name,
301                                  base::trace_event::TraceEventHandle handle,
302                                  base::PlatformThreadId thread_id,
303                                  bool explicit_timestamps,
304                                  const base::TimeTicks& now,
305                                  const base::ThreadTicks& thread_now);
306 
307 // These AddTraceEvent and AddTraceEventWithThreadIdAndTimestamp template
308 // functions are defined here instead of in the macro, because the arg_values
309 // could be temporary objects, such as `std::string`. In order to store
310 // pointers to the internal c_str and pass through to the tracing API,
311 // the arg_values must live throughout these procedures.
312 
313 template <class ARG1_TYPE>
314 inline base::trace_event::TraceEventHandle
AddTraceEventWithThreadIdAndTimestamp(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,base::PlatformThreadId thread_id,const base::TimeTicks & timestamp,unsigned int flags,uint64_t bind_id,const char * arg1_name,ARG1_TYPE && arg1_val)315 AddTraceEventWithThreadIdAndTimestamp(
316     char phase,
317     const unsigned char* category_group_enabled,
318     const char* name,
319     const char* scope,
320     uint64_t id,
321     base::PlatformThreadId thread_id,
322     const base::TimeTicks& timestamp,
323     unsigned int flags,
324     uint64_t bind_id,
325     const char* arg1_name,
326     ARG1_TYPE&& arg1_val) {
327   base::trace_event::TraceArguments args(arg1_name,
328                                          std::forward<ARG1_TYPE>(arg1_val));
329   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
330       phase, category_group_enabled, name, scope, id, bind_id, thread_id,
331       timestamp, &args, flags);
332 }
333 
334 template <class ARG1_TYPE, class ARG2_TYPE>
335 inline base::trace_event::TraceEventHandle
AddTraceEventWithThreadIdAndTimestamp(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,base::PlatformThreadId thread_id,const base::TimeTicks & timestamp,unsigned int flags,uint64_t bind_id,const char * arg1_name,ARG1_TYPE && arg1_val,const char * arg2_name,ARG2_TYPE && arg2_val)336 AddTraceEventWithThreadIdAndTimestamp(
337     char phase,
338     const unsigned char* category_group_enabled,
339     const char* name,
340     const char* scope,
341     uint64_t id,
342     base::PlatformThreadId thread_id,
343     const base::TimeTicks& timestamp,
344     unsigned int flags,
345     uint64_t bind_id,
346     const char* arg1_name,
347     ARG1_TYPE&& arg1_val,
348     const char* arg2_name,
349     ARG2_TYPE&& arg2_val) {
350   base::trace_event::TraceArguments args(
351       arg1_name, std::forward<ARG1_TYPE>(arg1_val), arg2_name,
352       std::forward<ARG2_TYPE>(arg2_val));
353   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
354       phase, category_group_enabled, name, scope, id, bind_id, thread_id,
355       timestamp, &args, flags);
356 }
357 
358 inline base::trace_event::TraceEventHandle
AddTraceEventWithThreadIdAndTimestamp(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,base::PlatformThreadId thread_id,const base::TimeTicks & timestamp,unsigned int flags,uint64_t bind_id)359 AddTraceEventWithThreadIdAndTimestamp(
360     char phase,
361     const unsigned char* category_group_enabled,
362     const char* name,
363     const char* scope,
364     uint64_t id,
365     base::PlatformThreadId thread_id,
366     const base::TimeTicks& timestamp,
367     unsigned int flags,
368     uint64_t bind_id) {
369   return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
370       phase, category_group_enabled, name, scope, id, bind_id, thread_id,
371       timestamp, nullptr, flags);
372 }
373 
AddTraceEvent(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,unsigned int flags,uint64_t bind_id)374 inline base::trace_event::TraceEventHandle AddTraceEvent(
375     char phase,
376     const unsigned char* category_group_enabled,
377     const char* name,
378     const char* scope,
379     uint64_t id,
380     unsigned int flags,
381     uint64_t bind_id) {
382   return AddTraceEventWithThreadIdAndTimestamp(
383       phase, category_group_enabled, name, scope, id,
384       TRACE_EVENT_API_CURRENT_THREAD_ID, TRACE_TIME_TICKS_NOW(), flags,
385       bind_id);
386 }
387 
388 template <class ARG1_TYPE>
AddTraceEvent(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,unsigned int flags,uint64_t bind_id,const char * arg1_name,ARG1_TYPE && arg1_val)389 inline base::trace_event::TraceEventHandle AddTraceEvent(
390     char phase,
391     const unsigned char* category_group_enabled,
392     const char* name,
393     const char* scope,
394     uint64_t id,
395     unsigned int flags,
396     uint64_t bind_id,
397     const char* arg1_name,
398     ARG1_TYPE&& arg1_val) {
399   return AddTraceEventWithThreadIdAndTimestamp(
400       phase, category_group_enabled, name, scope, id,
401       TRACE_EVENT_API_CURRENT_THREAD_ID, TRACE_TIME_TICKS_NOW(), flags, bind_id,
402       arg1_name, std::forward<ARG1_TYPE>(arg1_val));
403 }
404 
405 template <class ARG1_TYPE, class ARG2_TYPE>
AddTraceEvent(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,unsigned int flags,uint64_t bind_id,const char * arg1_name,ARG1_TYPE && arg1_val,const char * arg2_name,ARG2_TYPE && arg2_val)406 inline base::trace_event::TraceEventHandle AddTraceEvent(
407     char phase,
408     const unsigned char* category_group_enabled,
409     const char* name,
410     const char* scope,
411     uint64_t id,
412     unsigned int flags,
413     uint64_t bind_id,
414     const char* arg1_name,
415     ARG1_TYPE&& arg1_val,
416     const char* arg2_name,
417     ARG2_TYPE&& arg2_val) {
418   return AddTraceEventWithThreadIdAndTimestamp(
419       phase, category_group_enabled, name, scope, id,
420       TRACE_EVENT_API_CURRENT_THREAD_ID, TRACE_TIME_TICKS_NOW(), flags, bind_id,
421       arg1_name, std::forward<ARG1_TYPE>(arg1_val), arg2_name,
422       std::forward<ARG2_TYPE>(arg2_val));
423 }
424 
425 template <class ARG1_TYPE>
AddMetadataEvent(const unsigned char * category_group_enabled,const char * event_name,const char * arg_name,ARG1_TYPE && arg_val)426 void AddMetadataEvent(const unsigned char* category_group_enabled,
427                       const char* event_name,
428                       const char* arg_name,
429                       ARG1_TYPE&& arg_val) {
430   base::trace_event::TraceArguments args(arg_name,
431                                          std::forward<ARG1_TYPE>(arg_val));
432   trace_event_internal::AddMetadataEvent(category_group_enabled, event_name,
433                                          &args, TRACE_EVENT_FLAG_NONE);
434 }
435 
436 }  // namespace trace_event_internal
437 
438 namespace base {
439 namespace trace_event {
440 
441 template <typename IDType, const char* category>
442 class TraceScopedTrackableObject {
443  public:
TraceScopedTrackableObject(const char * name,IDType id)444   TraceScopedTrackableObject(const char* name, IDType id)
445       : name_(name), id_(id) {
446     TRACE_EVENT_OBJECT_CREATED_WITH_ID(category, name_, id_);
447   }
448   TraceScopedTrackableObject(const TraceScopedTrackableObject&) = delete;
449   TraceScopedTrackableObject& operator=(const TraceScopedTrackableObject&) =
450       delete;
451 
snapshot(ArgType snapshot)452   template <typename ArgType> void snapshot(ArgType snapshot) {
453     TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category, name_, id_, snapshot);
454   }
455 
~TraceScopedTrackableObject()456   ~TraceScopedTrackableObject() {
457     TRACE_EVENT_OBJECT_DELETED_WITH_ID(category, name_, id_);
458   }
459 
460  private:
461   const char* name_;
462   IDType id_;
463 };
464 
465 }  // namespace trace_event
466 }  // namespace base
467 
468 #endif  // BASE_TRACE_EVENT_TRACE_EVENT_H_
469