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 <stdint.h> 10 11 #include <memory> 12 #include <string> 13 #include <vector> 14 15 #include "base/atomicops.h" 16 #include "base/base_export.h" 17 #include "base/callback.h" 18 #include "base/containers/hash_tables.h" 19 #include "base/macros.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_local.h" 26 #include "base/trace_event/trace_event_memory_overhead.h" 27 #include "build/build_config.h" 28 29 namespace base { 30 namespace trace_event { 31 32 typedef base::Callback<bool(const char* arg_name)> ArgumentNameFilterPredicate; 33 34 typedef base::Callback<bool(const char* category_group_name, 35 const char* event_name, 36 ArgumentNameFilterPredicate*)> 37 ArgumentFilterPredicate; 38 39 // For any argument of type TRACE_VALUE_TYPE_CONVERTABLE the provided 40 // class must implement this interface. 41 class BASE_EXPORT ConvertableToTraceFormat { 42 public: 43 ConvertableToTraceFormat() = default; 44 virtual ~ConvertableToTraceFormat() = default; 45 46 // Append the class info to the provided |out| string. The appended 47 // data must be a valid JSON object. Strings must be properly quoted, and 48 // escaped. There is no processing applied to the content after it is 49 // appended. 50 virtual void AppendAsTraceFormat(std::string* out) const = 0; 51 52 virtual void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); 53 ToString()54 std::string ToString() const { 55 std::string result; 56 AppendAsTraceFormat(&result); 57 return result; 58 } 59 60 private: 61 DISALLOW_COPY_AND_ASSIGN(ConvertableToTraceFormat); 62 }; 63 64 const int kTraceMaxNumArgs = 2; 65 66 struct TraceEventHandle { 67 uint32_t chunk_seq; 68 // These numbers of bits must be kept consistent with 69 // TraceBufferChunk::kMaxTrunkIndex and 70 // TraceBufferChunk::kTraceBufferChunkSize (in trace_buffer.h). 71 unsigned chunk_index : 26; 72 unsigned event_index : 6; 73 }; 74 75 class BASE_EXPORT TraceEvent { 76 public: 77 union TraceValue { 78 bool as_bool; 79 unsigned long long as_uint; 80 long long as_int; 81 double as_double; 82 const void* as_pointer; 83 const char* as_string; 84 }; 85 86 TraceEvent(); 87 ~TraceEvent(); 88 89 void MoveFrom(std::unique_ptr<TraceEvent> other); 90 91 void Initialize(int 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 int num_args, 101 const char* const* arg_names, 102 const unsigned char* arg_types, 103 const unsigned long long* arg_values, 104 std::unique_ptr<ConvertableToTraceFormat>* convertable_values, 105 unsigned int flags); 106 107 void Reset(); 108 109 void UpdateDuration(const TimeTicks& now, const ThreadTicks& thread_now); 110 111 void EstimateTraceMemoryOverhead(TraceEventMemoryOverhead* overhead); 112 113 // Serialize event data to JSON 114 void AppendAsJSON( 115 std::string* out, 116 const ArgumentFilterPredicate& argument_filter_predicate) const; 117 void AppendPrettyPrinted(std::ostringstream* out) const; 118 119 static void AppendValueAsJSON(unsigned char type, 120 TraceValue value, 121 std::string* out); 122 timestamp()123 TimeTicks timestamp() const { return timestamp_; } thread_timestamp()124 ThreadTicks thread_timestamp() const { return thread_timestamp_; } phase()125 char phase() const { return phase_; } thread_id()126 int thread_id() const { return thread_id_; } duration()127 TimeDelta duration() const { return duration_; } thread_duration()128 TimeDelta thread_duration() const { return thread_duration_; } scope()129 const char* scope() const { return scope_; } id()130 unsigned long long id() const { return id_; } flags()131 unsigned int flags() const { return flags_; } bind_id()132 unsigned long long bind_id() const { return bind_id_; } 133 // Exposed for unittesting: 134 parameter_copy_storage()135 const std::string* parameter_copy_storage() const { 136 return parameter_copy_storage_.get(); 137 } 138 category_group_enabled()139 const unsigned char* category_group_enabled() const { 140 return category_group_enabled_; 141 } 142 name()143 const char* name() const { return name_; } 144 arg_type(size_t index)145 unsigned char arg_type(size_t index) const { return arg_types_[index]; } arg_name(size_t index)146 const char* arg_name(size_t index) const { return arg_names_[index]; } arg_value(size_t index)147 const TraceValue& arg_value(size_t index) const { return arg_values_[index]; } 148 arg_convertible_value(size_t index)149 const ConvertableToTraceFormat* arg_convertible_value(size_t index) const { 150 return convertable_values_[index].get(); 151 } 152 153 #if defined(OS_ANDROID) 154 void SendToATrace(); 155 #endif 156 157 private: 158 // Note: these are ordered by size (largest first) for optimal packing. 159 TimeTicks timestamp_; 160 ThreadTicks thread_timestamp_; 161 TimeDelta duration_; 162 TimeDelta thread_duration_; 163 // scope_ and id_ can be used to store phase-specific data. 164 const char* scope_; 165 unsigned long long id_; 166 TraceValue arg_values_[kTraceMaxNumArgs]; 167 const char* arg_names_[kTraceMaxNumArgs]; 168 std::unique_ptr<ConvertableToTraceFormat> 169 convertable_values_[kTraceMaxNumArgs]; 170 const unsigned char* category_group_enabled_; 171 const char* name_; 172 std::unique_ptr<std::string> parameter_copy_storage_; 173 // Depending on TRACE_EVENT_FLAG_HAS_PROCESS_ID the event will have either: 174 // tid: thread_id_, pid: current_process_id (default case). 175 // tid: -1, pid: process_id_ (when flags_ & TRACE_EVENT_FLAG_HAS_PROCESS_ID). 176 union { 177 int thread_id_; 178 int process_id_; 179 }; 180 unsigned int flags_; 181 unsigned long long bind_id_; 182 unsigned char arg_types_[kTraceMaxNumArgs]; 183 char phase_; 184 185 DISALLOW_COPY_AND_ASSIGN(TraceEvent); 186 }; 187 188 } // namespace trace_event 189 } // namespace base 190 191 #endif // BASE_TRACE_EVENT_TRACE_EVENT_IMPL_H_ 192