• 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 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #ifndef BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
11 #define BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
12 
13 #include <stdint.h>
14 
15 #include <memory>
16 #include <string>
17 
18 #include "base/base_export.h"
19 #include "base/compiler_specific.h"
20 #include "base/functional/callback.h"
21 #include "base/memory/raw_ptr.h"
22 #include "base/process/process_handle.h"
23 #include "base/strings/string_util.h"
24 #include "base/threading/platform_thread.h"
25 #include "base/time/time.h"
26 #include "base/trace_event/common/trace_event_common.h"
27 #include "base/trace_event/trace_arguments.h"
28 #include "base/trace_event/trace_event_memory_overhead.h"
29 #include "build/build_config.h"
30 
31 namespace base {
32 namespace trace_event {
33 
34 typedef base::RepeatingCallback<bool(const char* arg_name)>
35     ArgumentNameFilterPredicate;
36 
37 typedef base::RepeatingCallback<bool(const char* category_group_name,
38                                      const char* event_name,
39                                      ArgumentNameFilterPredicate*)>
40     ArgumentFilterPredicate;
41 
42 typedef base::RepeatingCallback<bool(const std::string& metadata_name)>
43     MetadataFilterPredicate;
44 
45 struct TraceEventHandle {
46   uint32_t chunk_seq;
47   // These numbers of bits must be kept consistent with
48   // TraceBufferChunk::kMaxTrunkIndex and
49   // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h).
50   unsigned chunk_index : 26;
51   unsigned event_index : 6;
52 };
53 
54 class BASE_EXPORT TraceEvent {
55  public:
56   // TODO(crbug.com/40599662): Remove once all users have been updated.
57   using TraceValue = base::trace_event::TraceValue;
58 
59   TraceEvent();
60 
61   TraceEvent(PlatformThreadId thread_id,
62              TimeTicks timestamp,
63              ThreadTicks thread_timestamp,
64              char phase,
65              const unsigned char* category_group_enabled,
66              const char* name,
67              const char* scope,
68              unsigned long long id,
69              unsigned long long bind_id,
70              TraceArguments* args,
71              unsigned int flags);
72 
73   TraceEvent(const TraceEvent&) = delete;
74   TraceEvent& operator=(const TraceEvent&) = delete;
75   ~TraceEvent();
76 
77   // Allow move operations.
78   TraceEvent(TraceEvent&&) noexcept;
79   TraceEvent& operator=(TraceEvent&&) noexcept;
80 
81   // Reset instance to empty state.
82   void Reset();
83 
84   // Reset instance to new state. This is equivalent but slightly more
85   // efficient than doing a move assignment, since it avoids creating
86   // temporary copies. I.e. compare these two statements:
87   //
88   //    event = TraceEvent(thread_id, ....);  // Create and destroy temporary.
89   //    event.Reset(thread_id, ...);  // Direct re-initialization.
90   //
91   void Reset(PlatformThreadId thread_id,
92              TimeTicks timestamp,
93              ThreadTicks thread_timestamp,
94              char phase,
95              const unsigned char* category_group_enabled,
96              const char* name,
97              const char* scope,
98              unsigned long long id,
99              unsigned long long bind_id,
100              TraceArguments* args,
101              unsigned int flags);
102 
103   void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now);
104 
105   void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead);
106 
107   // Serialize event data to JSON
108   void AppendAsJSON(
109       std::string* out,
110       const ArgumentFilterPredicate& argument_filter_predicate) const;
111   void AppendPrettyPrinted(std::ostringstream* out) const;
112 
timestamp()113   TimeTicks timestamp() const { return timestamp_; }
thread_timestamp()114   ThreadTicks thread_timestamp() const { return thread_timestamp_; }
phase()115   char phase() const { return phase_; }
thread_id()116   PlatformThreadId thread_id() const { return thread_id_; }
process_id()117   ProcessId process_id() const { return process_id_; }
duration()118   TimeDelta duration() const { return duration_; }
thread_duration()119   TimeDelta thread_duration() const { return thread_duration_; }
scope()120   const char* scope() const { return scope_; }
id()121   unsigned long long id() const { return id_; }
flags()122   unsigned int flags() const { return flags_; }
bind_id()123   unsigned long long bind_id() const { return bind_id_; }
124   // Exposed for unittesting:
125 
parameter_copy_storage()126   const StringStorage& parameter_copy_storage() const LIFETIME_BOUND {
127     return parameter_copy_storage_;
128   }
129 
category_group_enabled()130   const unsigned char* category_group_enabled() const {
131     return category_group_enabled_;
132   }
133 
name()134   const char* name() const { return name_; }
135 
arg_size()136   size_t arg_size() const { return args_.size(); }
arg_type(size_t index)137   unsigned char arg_type(size_t index) const { return args_.types()[index]; }
arg_name(size_t index)138   const char* arg_name(size_t index) const { return args_.names()[index]; }
arg_value(size_t index)139   const TraceValue& arg_value(size_t index) const {
140     return args_.values()[index];
141   }
142 
arg_convertible_value(size_t index)143   ConvertableToTraceFormat* arg_convertible_value(size_t index) {
144     return (arg_type(index) == TRACE_VALUE_TYPE_CONVERTABLE)
145                ? arg_value(index).as_convertable
146                : nullptr;
147   }
148 
149  private:
150   void InitArgs(TraceArguments* args);
151 
152   // Note: these are ordered by size (largest first) for optimal packing.
153   TimeTicks timestamp_ = TimeTicks();
154   ThreadTicks thread_timestamp_ = ThreadTicks();
155   TimeDelta duration_ = TimeDelta::FromInternalValue(-1);
156   TimeDelta thread_duration_ = TimeDelta();
157   // scope_ and id_ can be used to store phase-specific data.
158   // The following should be default-initialized to the expression
159   // trace_event_internal::kGlobalScope, which is nullptr, but its definition
160   // cannot be included here due to cyclical header dependencies.
161   // The equivalence is checked with a static_assert() in trace_event_impl.cc.
162   const char* scope_ = nullptr;
163   unsigned long long id_ = 0u;
164   raw_ptr<const unsigned char> category_group_enabled_ = nullptr;
165   const char* name_ = nullptr;
166   StringStorage parameter_copy_storage_;
167   TraceArguments args_;
168   // Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either:
169   //  tid: thread_id_, pid: current_process_id (default case).
170   //  tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID).
171   union {
172     PlatformThreadId thread_id_ = 0;
173     ProcessId process_id_;
174   };
175   unsigned int flags_ = 0;
176   unsigned long long bind_id_ = 0;
177   char phase_ = TRACE_EVENT_PHASE_BEGIN;
178 };
179 
180 }  // namespace trace_event
181 }  // namespace base
182 
183 #endif  // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_
184