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