1*6777b538SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/trace_log.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <cmath>
8*6777b538SAndroid Build Coastguard Worker #include <limits>
9*6777b538SAndroid Build Coastguard Worker #include <memory>
10*6777b538SAndroid Build Coastguard Worker #include <string_view>
11*6777b538SAndroid Build Coastguard Worker #include <unordered_set>
12*6777b538SAndroid Build Coastguard Worker #include <utility>
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker #include "base/auto_reset.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/base_switches.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/command_line.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/containers/contains.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/debug/leak_annotations.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/format_macros.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr_exclusion.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted_memory.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/no_destructor.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/process/process.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/process/process_metrics.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/ranges/algorithm.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_tokenizer.h"
35*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
36*6777b538SAndroid Build Coastguard Worker #include "base/system/sys_info.h"
37*6777b538SAndroid Build Coastguard Worker #include "base/task/current_thread.h"
38*6777b538SAndroid Build Coastguard Worker #include "base/task/sequenced_task_runner.h"
39*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
40*6777b538SAndroid Build Coastguard Worker #include "base/task/thread_pool.h"
41*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
42*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_id_name_manager.h"
43*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
44*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/heap_profiler.h"
45*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/heap_profiler_allocation_context_tracker.h"
46*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/memory_dump_manager.h"
47*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/memory_dump_provider.h"
48*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/process_memory_dump.h"
49*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/trace_buffer.h"
50*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/trace_event.h"
51*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
54*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
55*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
56*6777b538SAndroid Build Coastguard Worker #include "base/task/thread_pool/thread_pool_instance.h"
57*6777b538SAndroid Build Coastguard Worker #include "base/tracing/perfetto_platform.h"
58*6777b538SAndroid Build Coastguard Worker #include "third_party/perfetto/include/perfetto/ext/trace_processor/export_json.h" // nogncheck
59*6777b538SAndroid Build Coastguard Worker #include "third_party/perfetto/include/perfetto/trace_processor/trace_processor_storage.h" // nogncheck
60*6777b538SAndroid Build Coastguard Worker #include "third_party/perfetto/include/perfetto/tracing/console_interceptor.h"
61*6777b538SAndroid Build Coastguard Worker #include "third_party/perfetto/protos/perfetto/config/chrome/chrome_config.gen.h" // nogncheck
62*6777b538SAndroid Build Coastguard Worker #include "third_party/perfetto/protos/perfetto/config/interceptor_config.gen.h" // nogncheck
63*6777b538SAndroid Build Coastguard Worker #include "third_party/perfetto/protos/perfetto/trace/track_event/process_descriptor.gen.h" // nogncheck
64*6777b538SAndroid Build Coastguard Worker #include "third_party/perfetto/protos/perfetto/trace/track_event/thread_descriptor.gen.h" // nogncheck
65*6777b538SAndroid Build Coastguard Worker #endif
66*6777b538SAndroid Build Coastguard Worker
67*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
68*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/trace_event_etw_export_win.h"
69*6777b538SAndroid Build Coastguard Worker #endif
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
72*6777b538SAndroid Build Coastguard Worker #include "base/debug/elf_reader.h"
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker // The linker assigns the virtual address of the start of current library to
75*6777b538SAndroid Build Coastguard Worker // this symbol.
76*6777b538SAndroid Build Coastguard Worker extern char __executable_start;
77*6777b538SAndroid Build Coastguard Worker #endif
78*6777b538SAndroid Build Coastguard Worker
79*6777b538SAndroid Build Coastguard Worker namespace base {
80*6777b538SAndroid Build Coastguard Worker namespace trace_event {
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker namespace {
83*6777b538SAndroid Build Coastguard Worker
84*6777b538SAndroid Build Coastguard Worker // Controls the number of trace events we will buffer in-memory
85*6777b538SAndroid Build Coastguard Worker // before throwing them away.
86*6777b538SAndroid Build Coastguard Worker const size_t kTraceBufferChunkSize = TraceBufferChunk::kTraceBufferChunkSize;
87*6777b538SAndroid Build Coastguard Worker
88*6777b538SAndroid Build Coastguard Worker const size_t kTraceEventVectorBigBufferChunks =
89*6777b538SAndroid Build Coastguard Worker 512000000 / kTraceBufferChunkSize;
90*6777b538SAndroid Build Coastguard Worker static_assert(
91*6777b538SAndroid Build Coastguard Worker kTraceEventVectorBigBufferChunks <= TraceBufferChunk::kMaxChunkIndex,
92*6777b538SAndroid Build Coastguard Worker "Too many big buffer chunks");
93*6777b538SAndroid Build Coastguard Worker const size_t kTraceEventVectorBufferChunks = 256000 / kTraceBufferChunkSize;
94*6777b538SAndroid Build Coastguard Worker static_assert(
95*6777b538SAndroid Build Coastguard Worker kTraceEventVectorBufferChunks <= TraceBufferChunk::kMaxChunkIndex,
96*6777b538SAndroid Build Coastguard Worker "Too many vector buffer chunks");
97*6777b538SAndroid Build Coastguard Worker const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4;
98*6777b538SAndroid Build Coastguard Worker
99*6777b538SAndroid Build Coastguard Worker // ECHO_TO_CONSOLE needs a small buffer to hold the unfinished COMPLETE events.
100*6777b538SAndroid Build Coastguard Worker const size_t kEchoToConsoleTraceEventBufferChunks = 256;
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Worker const size_t kTraceEventBufferSizeInBytes = 100 * 1024;
103*6777b538SAndroid Build Coastguard Worker
104*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
105*6777b538SAndroid Build Coastguard Worker bool g_perfetto_initialized_by_tracelog = false;
106*6777b538SAndroid Build Coastguard Worker #else
107*6777b538SAndroid Build Coastguard Worker constexpr TimeDelta kThreadFlushTimeout = Seconds(3);
108*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
109*6777b538SAndroid Build Coastguard Worker
110*6777b538SAndroid Build Coastguard Worker TraceLog* g_trace_log_for_testing = nullptr;
111*6777b538SAndroid Build Coastguard Worker
112*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local TraceLog::ThreadLocalEventBuffer*
113*6777b538SAndroid Build Coastguard Worker thread_local_event_buffer = nullptr;
114*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local bool thread_blocks_message_loop = false;
115*6777b538SAndroid Build Coastguard Worker ABSL_CONST_INIT thread_local bool thread_is_in_trace_event = false;
116*6777b538SAndroid Build Coastguard Worker
ThreadNow()117*6777b538SAndroid Build Coastguard Worker ThreadTicks ThreadNow() {
118*6777b538SAndroid Build Coastguard Worker return ThreadTicks::IsSupported()
119*6777b538SAndroid Build Coastguard Worker ? base::subtle::ThreadTicksNowIgnoringOverride()
120*6777b538SAndroid Build Coastguard Worker : ThreadTicks();
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker
123*6777b538SAndroid Build Coastguard Worker template <typename T>
InitializeMetadataEvent(TraceEvent * trace_event,PlatformThreadId thread_id,const char * metadata_name,const char * arg_name,const T & value)124*6777b538SAndroid Build Coastguard Worker void InitializeMetadataEvent(TraceEvent* trace_event,
125*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id,
126*6777b538SAndroid Build Coastguard Worker const char* metadata_name,
127*6777b538SAndroid Build Coastguard Worker const char* arg_name,
128*6777b538SAndroid Build Coastguard Worker const T& value) {
129*6777b538SAndroid Build Coastguard Worker if (!trace_event)
130*6777b538SAndroid Build Coastguard Worker return;
131*6777b538SAndroid Build Coastguard Worker
132*6777b538SAndroid Build Coastguard Worker TraceArguments args(arg_name, value);
133*6777b538SAndroid Build Coastguard Worker base::TimeTicks now = TRACE_TIME_TICKS_NOW();
134*6777b538SAndroid Build Coastguard Worker ThreadTicks thread_now;
135*6777b538SAndroid Build Coastguard Worker trace_event->Reset(
136*6777b538SAndroid Build Coastguard Worker thread_id, now, thread_now, TRACE_EVENT_PHASE_METADATA,
137*6777b538SAndroid Build Coastguard Worker TraceLog::GetInstance()->GetCategoryGroupEnabled("__metadata"),
138*6777b538SAndroid Build Coastguard Worker metadata_name,
139*6777b538SAndroid Build Coastguard Worker trace_event_internal::kGlobalScope, // scope
140*6777b538SAndroid Build Coastguard Worker trace_event_internal::kNoId, // id
141*6777b538SAndroid Build Coastguard Worker trace_event_internal::kNoId, // bind_id
142*6777b538SAndroid Build Coastguard Worker &args, TRACE_EVENT_FLAG_NONE);
143*6777b538SAndroid Build Coastguard Worker }
144*6777b538SAndroid Build Coastguard Worker
145*6777b538SAndroid Build Coastguard Worker // Use this function instead of TraceEventHandle constructor to keep the
146*6777b538SAndroid Build Coastguard Worker // overhead of ScopedTracer (trace_event.h) constructor minimum.
MakeHandle(uint32_t chunk_seq,size_t chunk_index,size_t event_index,TraceEventHandle * handle)147*6777b538SAndroid Build Coastguard Worker void MakeHandle(uint32_t chunk_seq,
148*6777b538SAndroid Build Coastguard Worker size_t chunk_index,
149*6777b538SAndroid Build Coastguard Worker size_t event_index,
150*6777b538SAndroid Build Coastguard Worker TraceEventHandle* handle) {
151*6777b538SAndroid Build Coastguard Worker DCHECK(chunk_seq);
152*6777b538SAndroid Build Coastguard Worker DCHECK(chunk_index <= TraceBufferChunk::kMaxChunkIndex);
153*6777b538SAndroid Build Coastguard Worker DCHECK(event_index < TraceBufferChunk::kTraceBufferChunkSize);
154*6777b538SAndroid Build Coastguard Worker DCHECK(chunk_index <= std::numeric_limits<uint16_t>::max());
155*6777b538SAndroid Build Coastguard Worker handle->chunk_seq = chunk_seq;
156*6777b538SAndroid Build Coastguard Worker handle->chunk_index = static_cast<uint16_t>(chunk_index);
157*6777b538SAndroid Build Coastguard Worker handle->event_index = static_cast<uint16_t>(event_index);
158*6777b538SAndroid Build Coastguard Worker }
159*6777b538SAndroid Build Coastguard Worker
160*6777b538SAndroid Build Coastguard Worker // The fallback arguments filtering function will filter away every argument.
DefaultIsTraceEventArgsAllowlisted(const char * category_group_name,const char * event_name,base::trace_event::ArgumentNameFilterPredicate * arg_name_filter)161*6777b538SAndroid Build Coastguard Worker bool DefaultIsTraceEventArgsAllowlisted(
162*6777b538SAndroid Build Coastguard Worker const char* category_group_name,
163*6777b538SAndroid Build Coastguard Worker const char* event_name,
164*6777b538SAndroid Build Coastguard Worker base::trace_event::ArgumentNameFilterPredicate* arg_name_filter) {
165*6777b538SAndroid Build Coastguard Worker return false;
166*6777b538SAndroid Build Coastguard Worker }
167*6777b538SAndroid Build Coastguard Worker
168*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
169*6777b538SAndroid Build Coastguard Worker class PerfettoProtoAppender
170*6777b538SAndroid Build Coastguard Worker : public base::trace_event::ConvertableToTraceFormat::ProtoAppender {
171*6777b538SAndroid Build Coastguard Worker public:
PerfettoProtoAppender(perfetto::protos::pbzero::DebugAnnotation * proto)172*6777b538SAndroid Build Coastguard Worker explicit PerfettoProtoAppender(
173*6777b538SAndroid Build Coastguard Worker perfetto::protos::pbzero::DebugAnnotation* proto)
174*6777b538SAndroid Build Coastguard Worker : annotation_proto_(proto) {}
175*6777b538SAndroid Build Coastguard Worker ~PerfettoProtoAppender() override = default;
176*6777b538SAndroid Build Coastguard Worker
177*6777b538SAndroid Build Coastguard Worker // ProtoAppender implementation
AddBuffer(uint8_t * begin,uint8_t * end)178*6777b538SAndroid Build Coastguard Worker void AddBuffer(uint8_t* begin, uint8_t* end) override {
179*6777b538SAndroid Build Coastguard Worker ranges_.emplace_back();
180*6777b538SAndroid Build Coastguard Worker ranges_.back().begin = begin;
181*6777b538SAndroid Build Coastguard Worker ranges_.back().end = end;
182*6777b538SAndroid Build Coastguard Worker }
183*6777b538SAndroid Build Coastguard Worker
Finalize(uint32_t field_id)184*6777b538SAndroid Build Coastguard Worker size_t Finalize(uint32_t field_id) override {
185*6777b538SAndroid Build Coastguard Worker return annotation_proto_->AppendScatteredBytes(field_id, ranges_.data(),
186*6777b538SAndroid Build Coastguard Worker ranges_.size());
187*6777b538SAndroid Build Coastguard Worker }
188*6777b538SAndroid Build Coastguard Worker
189*6777b538SAndroid Build Coastguard Worker private:
190*6777b538SAndroid Build Coastguard Worker std::vector<protozero::ContiguousMemoryRange> ranges_;
191*6777b538SAndroid Build Coastguard Worker raw_ptr<perfetto::protos::pbzero::DebugAnnotation> annotation_proto_;
192*6777b538SAndroid Build Coastguard Worker };
193*6777b538SAndroid Build Coastguard Worker
AddConvertableToTraceFormat(base::trace_event::ConvertableToTraceFormat * value,perfetto::protos::pbzero::DebugAnnotation * annotation)194*6777b538SAndroid Build Coastguard Worker void AddConvertableToTraceFormat(
195*6777b538SAndroid Build Coastguard Worker base::trace_event::ConvertableToTraceFormat* value,
196*6777b538SAndroid Build Coastguard Worker perfetto::protos::pbzero::DebugAnnotation* annotation) {
197*6777b538SAndroid Build Coastguard Worker PerfettoProtoAppender proto_appender(annotation);
198*6777b538SAndroid Build Coastguard Worker if (value->AppendToProto(&proto_appender)) {
199*6777b538SAndroid Build Coastguard Worker return;
200*6777b538SAndroid Build Coastguard Worker }
201*6777b538SAndroid Build Coastguard Worker
202*6777b538SAndroid Build Coastguard Worker std::string json;
203*6777b538SAndroid Build Coastguard Worker value->AppendAsTraceFormat(&json);
204*6777b538SAndroid Build Coastguard Worker annotation->set_legacy_json_value(json.c_str());
205*6777b538SAndroid Build Coastguard Worker }
206*6777b538SAndroid Build Coastguard Worker
WriteDebugAnnotations(base::trace_event::TraceEvent * trace_event,perfetto::protos::pbzero::TrackEvent * track_event)207*6777b538SAndroid Build Coastguard Worker void WriteDebugAnnotations(base::trace_event::TraceEvent* trace_event,
208*6777b538SAndroid Build Coastguard Worker perfetto::protos::pbzero::TrackEvent* track_event) {
209*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < trace_event->arg_size() && trace_event->arg_name(i);
210*6777b538SAndroid Build Coastguard Worker ++i) {
211*6777b538SAndroid Build Coastguard Worker auto type = trace_event->arg_type(i);
212*6777b538SAndroid Build Coastguard Worker auto* annotation = track_event->add_debug_annotations();
213*6777b538SAndroid Build Coastguard Worker
214*6777b538SAndroid Build Coastguard Worker annotation->set_name(trace_event->arg_name(i));
215*6777b538SAndroid Build Coastguard Worker
216*6777b538SAndroid Build Coastguard Worker if (type == TRACE_VALUE_TYPE_CONVERTABLE) {
217*6777b538SAndroid Build Coastguard Worker AddConvertableToTraceFormat(trace_event->arg_convertible_value(i),
218*6777b538SAndroid Build Coastguard Worker annotation);
219*6777b538SAndroid Build Coastguard Worker continue;
220*6777b538SAndroid Build Coastguard Worker }
221*6777b538SAndroid Build Coastguard Worker
222*6777b538SAndroid Build Coastguard Worker auto& value = trace_event->arg_value(i);
223*6777b538SAndroid Build Coastguard Worker switch (type) {
224*6777b538SAndroid Build Coastguard Worker case TRACE_VALUE_TYPE_BOOL:
225*6777b538SAndroid Build Coastguard Worker annotation->set_bool_value(value.as_bool);
226*6777b538SAndroid Build Coastguard Worker break;
227*6777b538SAndroid Build Coastguard Worker case TRACE_VALUE_TYPE_UINT:
228*6777b538SAndroid Build Coastguard Worker annotation->set_uint_value(value.as_uint);
229*6777b538SAndroid Build Coastguard Worker break;
230*6777b538SAndroid Build Coastguard Worker case TRACE_VALUE_TYPE_INT:
231*6777b538SAndroid Build Coastguard Worker annotation->set_int_value(value.as_int);
232*6777b538SAndroid Build Coastguard Worker break;
233*6777b538SAndroid Build Coastguard Worker case TRACE_VALUE_TYPE_DOUBLE:
234*6777b538SAndroid Build Coastguard Worker annotation->set_double_value(value.as_double);
235*6777b538SAndroid Build Coastguard Worker break;
236*6777b538SAndroid Build Coastguard Worker case TRACE_VALUE_TYPE_POINTER:
237*6777b538SAndroid Build Coastguard Worker annotation->set_pointer_value(static_cast<uint64_t>(
238*6777b538SAndroid Build Coastguard Worker reinterpret_cast<uintptr_t>(value.as_pointer)));
239*6777b538SAndroid Build Coastguard Worker break;
240*6777b538SAndroid Build Coastguard Worker case TRACE_VALUE_TYPE_STRING:
241*6777b538SAndroid Build Coastguard Worker case TRACE_VALUE_TYPE_COPY_STRING:
242*6777b538SAndroid Build Coastguard Worker annotation->set_string_value(value.as_string ? value.as_string
243*6777b538SAndroid Build Coastguard Worker : "NULL");
244*6777b538SAndroid Build Coastguard Worker break;
245*6777b538SAndroid Build Coastguard Worker case TRACE_VALUE_TYPE_PROTO: {
246*6777b538SAndroid Build Coastguard Worker auto data = value.as_proto->SerializeAsArray();
247*6777b538SAndroid Build Coastguard Worker annotation->AppendRawProtoBytes(data.data(), data.size());
248*6777b538SAndroid Build Coastguard Worker } break;
249*6777b538SAndroid Build Coastguard Worker
250*6777b538SAndroid Build Coastguard Worker default:
251*6777b538SAndroid Build Coastguard Worker NOTREACHED() << "Don't know how to serialize this value";
252*6777b538SAndroid Build Coastguard Worker break;
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker }
255*6777b538SAndroid Build Coastguard Worker }
256*6777b538SAndroid Build Coastguard Worker
OnAddLegacyTraceEvent(TraceEvent * trace_event,bool thread_will_flush,base::trace_event::TraceEventHandle * handle)257*6777b538SAndroid Build Coastguard Worker void OnAddLegacyTraceEvent(TraceEvent* trace_event,
258*6777b538SAndroid Build Coastguard Worker bool thread_will_flush,
259*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceEventHandle* handle) {
260*6777b538SAndroid Build Coastguard Worker perfetto::DynamicCategory category(
261*6777b538SAndroid Build Coastguard Worker TraceLog::GetInstance()->GetCategoryGroupName(
262*6777b538SAndroid Build Coastguard Worker trace_event->category_group_enabled()));
263*6777b538SAndroid Build Coastguard Worker auto write_args = [trace_event](perfetto::EventContext ctx) {
264*6777b538SAndroid Build Coastguard Worker WriteDebugAnnotations(trace_event, ctx.event());
265*6777b538SAndroid Build Coastguard Worker uint32_t id_flags = trace_event->flags() & (TRACE_EVENT_FLAG_HAS_ID |
266*6777b538SAndroid Build Coastguard Worker TRACE_EVENT_FLAG_HAS_LOCAL_ID |
267*6777b538SAndroid Build Coastguard Worker TRACE_EVENT_FLAG_HAS_GLOBAL_ID);
268*6777b538SAndroid Build Coastguard Worker if (!id_flags &&
269*6777b538SAndroid Build Coastguard Worker perfetto::internal::TrackEventLegacy::PhaseToType(
270*6777b538SAndroid Build Coastguard Worker trace_event->phase()) !=
271*6777b538SAndroid Build Coastguard Worker perfetto::protos::pbzero::TrackEvent::TYPE_UNSPECIFIED) {
272*6777b538SAndroid Build Coastguard Worker return;
273*6777b538SAndroid Build Coastguard Worker }
274*6777b538SAndroid Build Coastguard Worker auto* legacy_event = ctx.event()->set_legacy_event();
275*6777b538SAndroid Build Coastguard Worker legacy_event->set_phase(trace_event->phase());
276*6777b538SAndroid Build Coastguard Worker switch (id_flags) {
277*6777b538SAndroid Build Coastguard Worker case TRACE_EVENT_FLAG_HAS_ID:
278*6777b538SAndroid Build Coastguard Worker legacy_event->set_unscoped_id(trace_event->id());
279*6777b538SAndroid Build Coastguard Worker break;
280*6777b538SAndroid Build Coastguard Worker case TRACE_EVENT_FLAG_HAS_LOCAL_ID:
281*6777b538SAndroid Build Coastguard Worker legacy_event->set_local_id(trace_event->id());
282*6777b538SAndroid Build Coastguard Worker break;
283*6777b538SAndroid Build Coastguard Worker case TRACE_EVENT_FLAG_HAS_GLOBAL_ID:
284*6777b538SAndroid Build Coastguard Worker legacy_event->set_global_id(trace_event->id());
285*6777b538SAndroid Build Coastguard Worker break;
286*6777b538SAndroid Build Coastguard Worker default:
287*6777b538SAndroid Build Coastguard Worker break;
288*6777b538SAndroid Build Coastguard Worker }
289*6777b538SAndroid Build Coastguard Worker };
290*6777b538SAndroid Build Coastguard Worker
291*6777b538SAndroid Build Coastguard Worker auto phase = trace_event->phase();
292*6777b538SAndroid Build Coastguard Worker auto flags = trace_event->flags();
293*6777b538SAndroid Build Coastguard Worker base::TimeTicks timestamp = trace_event->timestamp().is_null()
294*6777b538SAndroid Build Coastguard Worker ? TRACE_TIME_TICKS_NOW()
295*6777b538SAndroid Build Coastguard Worker : trace_event->timestamp();
296*6777b538SAndroid Build Coastguard Worker if (phase == TRACE_EVENT_PHASE_COMPLETE) {
297*6777b538SAndroid Build Coastguard Worker phase = TRACE_EVENT_PHASE_BEGIN;
298*6777b538SAndroid Build Coastguard Worker } else if (phase == TRACE_EVENT_PHASE_INSTANT) {
299*6777b538SAndroid Build Coastguard Worker auto scope = flags & TRACE_EVENT_FLAG_SCOPE_MASK;
300*6777b538SAndroid Build Coastguard Worker switch (scope) {
301*6777b538SAndroid Build Coastguard Worker case TRACE_EVENT_SCOPE_GLOBAL:
302*6777b538SAndroid Build Coastguard Worker PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(
303*6777b538SAndroid Build Coastguard Worker phase, category, trace_event->name(), ::perfetto::Track::Global(0),
304*6777b538SAndroid Build Coastguard Worker timestamp, write_args);
305*6777b538SAndroid Build Coastguard Worker return;
306*6777b538SAndroid Build Coastguard Worker case TRACE_EVENT_SCOPE_PROCESS:
307*6777b538SAndroid Build Coastguard Worker PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(
308*6777b538SAndroid Build Coastguard Worker phase, category, trace_event->name(),
309*6777b538SAndroid Build Coastguard Worker ::perfetto::ProcessTrack::Current(), timestamp, write_args);
310*6777b538SAndroid Build Coastguard Worker return;
311*6777b538SAndroid Build Coastguard Worker default:
312*6777b538SAndroid Build Coastguard Worker case TRACE_EVENT_SCOPE_THREAD: /* Fallthrough. */
313*6777b538SAndroid Build Coastguard Worker break;
314*6777b538SAndroid Build Coastguard Worker }
315*6777b538SAndroid Build Coastguard Worker }
316*6777b538SAndroid Build Coastguard Worker if (trace_event->thread_id() &&
317*6777b538SAndroid Build Coastguard Worker trace_event->thread_id() != base::PlatformThread::CurrentId()) {
318*6777b538SAndroid Build Coastguard Worker PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(
319*6777b538SAndroid Build Coastguard Worker phase, category, trace_event->name(),
320*6777b538SAndroid Build Coastguard Worker perfetto::ThreadTrack::ForThread(trace_event->thread_id()), timestamp,
321*6777b538SAndroid Build Coastguard Worker write_args);
322*6777b538SAndroid Build Coastguard Worker return;
323*6777b538SAndroid Build Coastguard Worker }
324*6777b538SAndroid Build Coastguard Worker PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(
325*6777b538SAndroid Build Coastguard Worker phase, category, trace_event->name(),
326*6777b538SAndroid Build Coastguard Worker perfetto::internal::TrackEventInternal::kDefaultTrack, timestamp,
327*6777b538SAndroid Build Coastguard Worker write_args);
328*6777b538SAndroid Build Coastguard Worker }
329*6777b538SAndroid Build Coastguard Worker
OnUpdateLegacyTraceEventDuration(const unsigned char * category_group_enabled,const char * name,TraceEventHandle handle,PlatformThreadId thread_id,bool explicit_timestamps,const TimeTicks & now,const ThreadTicks & thread_now)330*6777b538SAndroid Build Coastguard Worker void OnUpdateLegacyTraceEventDuration(
331*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
332*6777b538SAndroid Build Coastguard Worker const char* name,
333*6777b538SAndroid Build Coastguard Worker TraceEventHandle handle,
334*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id,
335*6777b538SAndroid Build Coastguard Worker bool explicit_timestamps,
336*6777b538SAndroid Build Coastguard Worker const TimeTicks& now,
337*6777b538SAndroid Build Coastguard Worker const ThreadTicks& thread_now) {
338*6777b538SAndroid Build Coastguard Worker perfetto::DynamicCategory category(
339*6777b538SAndroid Build Coastguard Worker TraceLog::GetInstance()->GetCategoryGroupName(category_group_enabled));
340*6777b538SAndroid Build Coastguard Worker auto phase = TRACE_EVENT_PHASE_END;
341*6777b538SAndroid Build Coastguard Worker base::TimeTicks timestamp =
342*6777b538SAndroid Build Coastguard Worker explicit_timestamps ? now : TRACE_TIME_TICKS_NOW();
343*6777b538SAndroid Build Coastguard Worker if (thread_id && thread_id != base::PlatformThread::CurrentId()) {
344*6777b538SAndroid Build Coastguard Worker PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(
345*6777b538SAndroid Build Coastguard Worker phase, category, name, perfetto::ThreadTrack::ForThread(thread_id),
346*6777b538SAndroid Build Coastguard Worker timestamp);
347*6777b538SAndroid Build Coastguard Worker return;
348*6777b538SAndroid Build Coastguard Worker }
349*6777b538SAndroid Build Coastguard Worker PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(
350*6777b538SAndroid Build Coastguard Worker phase, category, name,
351*6777b538SAndroid Build Coastguard Worker perfetto::internal::TrackEventInternal::kDefaultTrack, timestamp);
352*6777b538SAndroid Build Coastguard Worker }
353*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
354*6777b538SAndroid Build Coastguard Worker
355*6777b538SAndroid Build Coastguard Worker } // namespace
356*6777b538SAndroid Build Coastguard Worker
357*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_TRACE_PROCESSOR)
358*6777b538SAndroid Build Coastguard Worker namespace {
359*6777b538SAndroid Build Coastguard Worker // Perfetto provides us with a fully formed JSON trace file, while
360*6777b538SAndroid Build Coastguard Worker // TraceResultBuffer wants individual JSON fragments without a containing
361*6777b538SAndroid Build Coastguard Worker // object. We therefore need to strip away the outer object, including the
362*6777b538SAndroid Build Coastguard Worker // metadata fields, from the JSON stream.
363*6777b538SAndroid Build Coastguard Worker static constexpr char kJsonPrefix[] = "{\"traceEvents\":[\n";
364*6777b538SAndroid Build Coastguard Worker static constexpr char kJsonJoiner[] = ",\n";
365*6777b538SAndroid Build Coastguard Worker static constexpr char kJsonSuffix[] = "],\"metadata\":";
366*6777b538SAndroid Build Coastguard Worker } // namespace
367*6777b538SAndroid Build Coastguard Worker
368*6777b538SAndroid Build Coastguard Worker class JsonStringOutputWriter
369*6777b538SAndroid Build Coastguard Worker : public perfetto::trace_processor::json::OutputWriter {
370*6777b538SAndroid Build Coastguard Worker public:
JsonStringOutputWriter(scoped_refptr<SequencedTaskRunner> flush_task_runner,TraceLog::OutputCallback flush_callback)371*6777b538SAndroid Build Coastguard Worker JsonStringOutputWriter(scoped_refptr<SequencedTaskRunner> flush_task_runner,
372*6777b538SAndroid Build Coastguard Worker TraceLog::OutputCallback flush_callback)
373*6777b538SAndroid Build Coastguard Worker : flush_task_runner_(flush_task_runner),
374*6777b538SAndroid Build Coastguard Worker flush_callback_(std::move(flush_callback)) {
375*6777b538SAndroid Build Coastguard Worker buffer_->data().reserve(kBufferReserveCapacity);
376*6777b538SAndroid Build Coastguard Worker }
377*6777b538SAndroid Build Coastguard Worker
~JsonStringOutputWriter()378*6777b538SAndroid Build Coastguard Worker ~JsonStringOutputWriter() override { Flush(/*has_more=*/false); }
379*6777b538SAndroid Build Coastguard Worker
AppendString(const std::string & string)380*6777b538SAndroid Build Coastguard Worker perfetto::trace_processor::util::Status AppendString(
381*6777b538SAndroid Build Coastguard Worker const std::string& string) override {
382*6777b538SAndroid Build Coastguard Worker if (!did_strip_prefix_) {
383*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(string, kJsonPrefix);
384*6777b538SAndroid Build Coastguard Worker did_strip_prefix_ = true;
385*6777b538SAndroid Build Coastguard Worker return perfetto::trace_processor::util::OkStatus();
386*6777b538SAndroid Build Coastguard Worker } else if (buffer_->data().empty() &&
387*6777b538SAndroid Build Coastguard Worker !strncmp(string.c_str(), kJsonJoiner, strlen(kJsonJoiner))) {
388*6777b538SAndroid Build Coastguard Worker // We only remove the leading joiner comma for the first chunk in a buffer
389*6777b538SAndroid Build Coastguard Worker // since the consumer is expected to insert commas between the buffers we
390*6777b538SAndroid Build Coastguard Worker // provide.
391*6777b538SAndroid Build Coastguard Worker buffer_->data() += string.substr(strlen(kJsonJoiner));
392*6777b538SAndroid Build Coastguard Worker } else if (!strncmp(string.c_str(), kJsonSuffix, strlen(kJsonSuffix))) {
393*6777b538SAndroid Build Coastguard Worker return perfetto::trace_processor::util::OkStatus();
394*6777b538SAndroid Build Coastguard Worker } else {
395*6777b538SAndroid Build Coastguard Worker buffer_->data() += string;
396*6777b538SAndroid Build Coastguard Worker }
397*6777b538SAndroid Build Coastguard Worker if (buffer_->data().size() > kBufferLimitInBytes) {
398*6777b538SAndroid Build Coastguard Worker Flush(/*has_more=*/true);
399*6777b538SAndroid Build Coastguard Worker // Reset the buffer_ after moving it above.
400*6777b538SAndroid Build Coastguard Worker buffer_ = new RefCountedString();
401*6777b538SAndroid Build Coastguard Worker buffer_->data().reserve(kBufferReserveCapacity);
402*6777b538SAndroid Build Coastguard Worker }
403*6777b538SAndroid Build Coastguard Worker return perfetto::trace_processor::util::OkStatus();
404*6777b538SAndroid Build Coastguard Worker }
405*6777b538SAndroid Build Coastguard Worker
406*6777b538SAndroid Build Coastguard Worker private:
Flush(bool has_more)407*6777b538SAndroid Build Coastguard Worker void Flush(bool has_more) {
408*6777b538SAndroid Build Coastguard Worker if (flush_task_runner_) {
409*6777b538SAndroid Build Coastguard Worker flush_task_runner_->PostTask(
410*6777b538SAndroid Build Coastguard Worker FROM_HERE,
411*6777b538SAndroid Build Coastguard Worker base::BindOnce(flush_callback_, std::move(buffer_), has_more));
412*6777b538SAndroid Build Coastguard Worker } else {
413*6777b538SAndroid Build Coastguard Worker flush_callback_.Run(std::move(buffer_), has_more);
414*6777b538SAndroid Build Coastguard Worker }
415*6777b538SAndroid Build Coastguard Worker }
416*6777b538SAndroid Build Coastguard Worker
417*6777b538SAndroid Build Coastguard Worker static constexpr size_t kBufferLimitInBytes = 100 * 1024;
418*6777b538SAndroid Build Coastguard Worker // Since we write each string before checking the limit, we'll always go
419*6777b538SAndroid Build Coastguard Worker // slightly over and hence we reserve some extra space to avoid most
420*6777b538SAndroid Build Coastguard Worker // reallocs.
421*6777b538SAndroid Build Coastguard Worker static constexpr size_t kBufferReserveCapacity = kBufferLimitInBytes * 5 / 4;
422*6777b538SAndroid Build Coastguard Worker
423*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> flush_task_runner_;
424*6777b538SAndroid Build Coastguard Worker TraceLog::OutputCallback flush_callback_;
425*6777b538SAndroid Build Coastguard Worker scoped_refptr<RefCountedString> buffer_ = new RefCountedString();
426*6777b538SAndroid Build Coastguard Worker bool did_strip_prefix_ = false;
427*6777b538SAndroid Build Coastguard Worker };
428*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(USE_PERFETTO_TRACE_PROCESSOR)
429*6777b538SAndroid Build Coastguard Worker
430*6777b538SAndroid Build Coastguard Worker // A helper class that allows the lock to be acquired in the middle of the scope
431*6777b538SAndroid Build Coastguard Worker // and unlocks at the end of scope if locked.
432*6777b538SAndroid Build Coastguard Worker class TraceLog::OptionalAutoLock {
433*6777b538SAndroid Build Coastguard Worker public:
OptionalAutoLock(Lock * lock)434*6777b538SAndroid Build Coastguard Worker explicit OptionalAutoLock(Lock* lock) : lock_(lock) {}
435*6777b538SAndroid Build Coastguard Worker
436*6777b538SAndroid Build Coastguard Worker OptionalAutoLock(const OptionalAutoLock&) = delete;
437*6777b538SAndroid Build Coastguard Worker OptionalAutoLock& operator=(const OptionalAutoLock&) = delete;
438*6777b538SAndroid Build Coastguard Worker
~OptionalAutoLock()439*6777b538SAndroid Build Coastguard Worker ~OptionalAutoLock() {
440*6777b538SAndroid Build Coastguard Worker if (locked_)
441*6777b538SAndroid Build Coastguard Worker lock_->Release();
442*6777b538SAndroid Build Coastguard Worker }
443*6777b538SAndroid Build Coastguard Worker
EnsureAcquired()444*6777b538SAndroid Build Coastguard Worker void EnsureAcquired() EXCLUSIVE_LOCK_FUNCTION(lock_) {
445*6777b538SAndroid Build Coastguard Worker if (!locked_) {
446*6777b538SAndroid Build Coastguard Worker lock_->Acquire();
447*6777b538SAndroid Build Coastguard Worker locked_ = true;
448*6777b538SAndroid Build Coastguard Worker } else {
449*6777b538SAndroid Build Coastguard Worker lock_->AssertAcquired();
450*6777b538SAndroid Build Coastguard Worker }
451*6777b538SAndroid Build Coastguard Worker }
452*6777b538SAndroid Build Coastguard Worker
453*6777b538SAndroid Build Coastguard Worker private:
454*6777b538SAndroid Build Coastguard Worker // This field is not a raw_ptr<> because it is needed for lock annotations.
455*6777b538SAndroid Build Coastguard Worker RAW_PTR_EXCLUSION Lock* lock_;
456*6777b538SAndroid Build Coastguard Worker bool locked_ = false;
457*6777b538SAndroid Build Coastguard Worker };
458*6777b538SAndroid Build Coastguard Worker
459*6777b538SAndroid Build Coastguard Worker class TraceLog::ThreadLocalEventBuffer
460*6777b538SAndroid Build Coastguard Worker : public CurrentThread::DestructionObserver,
461*6777b538SAndroid Build Coastguard Worker public MemoryDumpProvider {
462*6777b538SAndroid Build Coastguard Worker public:
463*6777b538SAndroid Build Coastguard Worker explicit ThreadLocalEventBuffer(TraceLog* trace_log);
464*6777b538SAndroid Build Coastguard Worker ThreadLocalEventBuffer(const ThreadLocalEventBuffer&) = delete;
465*6777b538SAndroid Build Coastguard Worker ThreadLocalEventBuffer& operator=(const ThreadLocalEventBuffer&) = delete;
466*6777b538SAndroid Build Coastguard Worker ~ThreadLocalEventBuffer() override;
467*6777b538SAndroid Build Coastguard Worker
468*6777b538SAndroid Build Coastguard Worker TraceEvent* AddTraceEvent(TraceEventHandle* handle);
469*6777b538SAndroid Build Coastguard Worker
GetEventByHandle(TraceEventHandle handle)470*6777b538SAndroid Build Coastguard Worker TraceEvent* GetEventByHandle(TraceEventHandle handle) {
471*6777b538SAndroid Build Coastguard Worker if (!chunk_ || handle.chunk_seq != chunk_->seq() ||
472*6777b538SAndroid Build Coastguard Worker handle.chunk_index != chunk_index_) {
473*6777b538SAndroid Build Coastguard Worker return nullptr;
474*6777b538SAndroid Build Coastguard Worker }
475*6777b538SAndroid Build Coastguard Worker
476*6777b538SAndroid Build Coastguard Worker return chunk_->GetEventAt(handle.event_index);
477*6777b538SAndroid Build Coastguard Worker }
478*6777b538SAndroid Build Coastguard Worker
generation() const479*6777b538SAndroid Build Coastguard Worker int generation() const { return generation_; }
480*6777b538SAndroid Build Coastguard Worker
481*6777b538SAndroid Build Coastguard Worker private:
482*6777b538SAndroid Build Coastguard Worker // CurrentThread::DestructionObserver
483*6777b538SAndroid Build Coastguard Worker void WillDestroyCurrentMessageLoop() override;
484*6777b538SAndroid Build Coastguard Worker
485*6777b538SAndroid Build Coastguard Worker // MemoryDumpProvider implementation.
486*6777b538SAndroid Build Coastguard Worker bool OnMemoryDump(const MemoryDumpArgs& args,
487*6777b538SAndroid Build Coastguard Worker ProcessMemoryDump* pmd) override;
488*6777b538SAndroid Build Coastguard Worker
489*6777b538SAndroid Build Coastguard Worker void FlushWhileLocked();
490*6777b538SAndroid Build Coastguard Worker
CheckThisIsCurrentBuffer() const491*6777b538SAndroid Build Coastguard Worker void CheckThisIsCurrentBuffer() const {
492*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(thread_local_event_buffer, this);
493*6777b538SAndroid Build Coastguard Worker }
494*6777b538SAndroid Build Coastguard Worker
495*6777b538SAndroid Build Coastguard Worker const AutoReset<ThreadLocalEventBuffer*> resetter_{&thread_local_event_buffer,
496*6777b538SAndroid Build Coastguard Worker this, nullptr};
497*6777b538SAndroid Build Coastguard Worker // Since TraceLog is a leaky singleton, trace_log_ will always be valid
498*6777b538SAndroid Build Coastguard Worker // as long as the thread exists.
499*6777b538SAndroid Build Coastguard Worker raw_ptr<TraceLog> trace_log_;
500*6777b538SAndroid Build Coastguard Worker std::unique_ptr<TraceBufferChunk> chunk_;
501*6777b538SAndroid Build Coastguard Worker size_t chunk_index_ = 0;
502*6777b538SAndroid Build Coastguard Worker int generation_;
503*6777b538SAndroid Build Coastguard Worker };
504*6777b538SAndroid Build Coastguard Worker
ThreadLocalEventBuffer(TraceLog * trace_log)505*6777b538SAndroid Build Coastguard Worker TraceLog::ThreadLocalEventBuffer::ThreadLocalEventBuffer(TraceLog* trace_log)
506*6777b538SAndroid Build Coastguard Worker : trace_log_(trace_log),
507*6777b538SAndroid Build Coastguard Worker generation_(trace_log->generation()) {
508*6777b538SAndroid Build Coastguard Worker // ThreadLocalEventBuffer is created only if the thread has a message loop, so
509*6777b538SAndroid Build Coastguard Worker // the following message_loop won't be NULL.
510*6777b538SAndroid Build Coastguard Worker CurrentThread::Get()->AddDestructionObserver(this);
511*6777b538SAndroid Build Coastguard Worker
512*6777b538SAndroid Build Coastguard Worker // This is to report the local memory usage when memory-infra is enabled.
513*6777b538SAndroid Build Coastguard Worker MemoryDumpManager::GetInstance()->RegisterDumpProvider(
514*6777b538SAndroid Build Coastguard Worker this, "ThreadLocalEventBuffer",
515*6777b538SAndroid Build Coastguard Worker SingleThreadTaskRunner::GetCurrentDefault());
516*6777b538SAndroid Build Coastguard Worker
517*6777b538SAndroid Build Coastguard Worker auto thread_id = PlatformThread::CurrentId();
518*6777b538SAndroid Build Coastguard Worker
519*6777b538SAndroid Build Coastguard Worker AutoLock lock(trace_log->lock_);
520*6777b538SAndroid Build Coastguard Worker trace_log->thread_task_runners_[thread_id] =
521*6777b538SAndroid Build Coastguard Worker SingleThreadTaskRunner::GetCurrentDefault();
522*6777b538SAndroid Build Coastguard Worker }
523*6777b538SAndroid Build Coastguard Worker
~ThreadLocalEventBuffer()524*6777b538SAndroid Build Coastguard Worker TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() {
525*6777b538SAndroid Build Coastguard Worker CheckThisIsCurrentBuffer();
526*6777b538SAndroid Build Coastguard Worker CurrentThread::Get()->RemoveDestructionObserver(this);
527*6777b538SAndroid Build Coastguard Worker MemoryDumpManager::GetInstance()->UnregisterDumpProvider(this);
528*6777b538SAndroid Build Coastguard Worker
529*6777b538SAndroid Build Coastguard Worker AutoLock lock(trace_log_->lock_);
530*6777b538SAndroid Build Coastguard Worker FlushWhileLocked();
531*6777b538SAndroid Build Coastguard Worker trace_log_->thread_task_runners_.erase(PlatformThread::CurrentId());
532*6777b538SAndroid Build Coastguard Worker }
533*6777b538SAndroid Build Coastguard Worker
AddTraceEvent(TraceEventHandle * handle)534*6777b538SAndroid Build Coastguard Worker TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent(
535*6777b538SAndroid Build Coastguard Worker TraceEventHandle* handle) {
536*6777b538SAndroid Build Coastguard Worker CheckThisIsCurrentBuffer();
537*6777b538SAndroid Build Coastguard Worker
538*6777b538SAndroid Build Coastguard Worker if (chunk_ && chunk_->IsFull()) {
539*6777b538SAndroid Build Coastguard Worker AutoLock lock(trace_log_->lock_);
540*6777b538SAndroid Build Coastguard Worker FlushWhileLocked();
541*6777b538SAndroid Build Coastguard Worker chunk_.reset();
542*6777b538SAndroid Build Coastguard Worker }
543*6777b538SAndroid Build Coastguard Worker if (!chunk_) {
544*6777b538SAndroid Build Coastguard Worker AutoLock lock(trace_log_->lock_);
545*6777b538SAndroid Build Coastguard Worker chunk_ = trace_log_->logged_events_->GetChunk(&chunk_index_);
546*6777b538SAndroid Build Coastguard Worker trace_log_->CheckIfBufferIsFullWhileLocked();
547*6777b538SAndroid Build Coastguard Worker }
548*6777b538SAndroid Build Coastguard Worker if (!chunk_)
549*6777b538SAndroid Build Coastguard Worker return nullptr;
550*6777b538SAndroid Build Coastguard Worker
551*6777b538SAndroid Build Coastguard Worker size_t event_index;
552*6777b538SAndroid Build Coastguard Worker TraceEvent* trace_event = chunk_->AddTraceEvent(&event_index);
553*6777b538SAndroid Build Coastguard Worker if (trace_event && handle)
554*6777b538SAndroid Build Coastguard Worker MakeHandle(chunk_->seq(), chunk_index_, event_index, handle);
555*6777b538SAndroid Build Coastguard Worker
556*6777b538SAndroid Build Coastguard Worker return trace_event;
557*6777b538SAndroid Build Coastguard Worker }
558*6777b538SAndroid Build Coastguard Worker
WillDestroyCurrentMessageLoop()559*6777b538SAndroid Build Coastguard Worker void TraceLog::ThreadLocalEventBuffer::WillDestroyCurrentMessageLoop() {
560*6777b538SAndroid Build Coastguard Worker delete this;
561*6777b538SAndroid Build Coastguard Worker }
562*6777b538SAndroid Build Coastguard Worker
OnMemoryDump(const MemoryDumpArgs & args,ProcessMemoryDump * pmd)563*6777b538SAndroid Build Coastguard Worker bool TraceLog::ThreadLocalEventBuffer::OnMemoryDump(const MemoryDumpArgs& args,
564*6777b538SAndroid Build Coastguard Worker ProcessMemoryDump* pmd) {
565*6777b538SAndroid Build Coastguard Worker if (!chunk_)
566*6777b538SAndroid Build Coastguard Worker return true;
567*6777b538SAndroid Build Coastguard Worker std::string dump_base_name =
568*6777b538SAndroid Build Coastguard Worker "tracing/thread_" + NumberToString(PlatformThread::CurrentId());
569*6777b538SAndroid Build Coastguard Worker TraceEventMemoryOverhead overhead;
570*6777b538SAndroid Build Coastguard Worker chunk_->EstimateTraceMemoryOverhead(&overhead);
571*6777b538SAndroid Build Coastguard Worker overhead.DumpInto(dump_base_name.c_str(), pmd);
572*6777b538SAndroid Build Coastguard Worker return true;
573*6777b538SAndroid Build Coastguard Worker }
574*6777b538SAndroid Build Coastguard Worker
FlushWhileLocked()575*6777b538SAndroid Build Coastguard Worker void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() {
576*6777b538SAndroid Build Coastguard Worker if (!chunk_)
577*6777b538SAndroid Build Coastguard Worker return;
578*6777b538SAndroid Build Coastguard Worker
579*6777b538SAndroid Build Coastguard Worker trace_log_->lock_.AssertAcquired();
580*6777b538SAndroid Build Coastguard Worker if (trace_log_->CheckGeneration(generation_)) {
581*6777b538SAndroid Build Coastguard Worker // Return the chunk to the buffer only if the generation matches.
582*6777b538SAndroid Build Coastguard Worker trace_log_->logged_events_->ReturnChunk(chunk_index_, std::move(chunk_));
583*6777b538SAndroid Build Coastguard Worker }
584*6777b538SAndroid Build Coastguard Worker // Otherwise this method may be called from the destructor, or TraceLog will
585*6777b538SAndroid Build Coastguard Worker // find the generation mismatch and delete this buffer soon.
586*6777b538SAndroid Build Coastguard Worker }
587*6777b538SAndroid Build Coastguard Worker
SetAddTraceEventOverrides(const AddTraceEventOverrideFunction & add_event_override,const OnFlushFunction & on_flush_override,const UpdateDurationFunction & update_duration_override)588*6777b538SAndroid Build Coastguard Worker void TraceLog::SetAddTraceEventOverrides(
589*6777b538SAndroid Build Coastguard Worker const AddTraceEventOverrideFunction& add_event_override,
590*6777b538SAndroid Build Coastguard Worker const OnFlushFunction& on_flush_override,
591*6777b538SAndroid Build Coastguard Worker const UpdateDurationFunction& update_duration_override) {
592*6777b538SAndroid Build Coastguard Worker add_trace_event_override_.store(add_event_override);
593*6777b538SAndroid Build Coastguard Worker on_flush_override_.store(on_flush_override);
594*6777b538SAndroid Build Coastguard Worker update_duration_override_.store(update_duration_override);
595*6777b538SAndroid Build Coastguard Worker }
596*6777b538SAndroid Build Coastguard Worker
597*6777b538SAndroid Build Coastguard Worker struct TraceLog::RegisteredAsyncObserver {
RegisteredAsyncObserverbase::trace_event::TraceLog::RegisteredAsyncObserver598*6777b538SAndroid Build Coastguard Worker explicit RegisteredAsyncObserver(WeakPtr<AsyncEnabledStateObserver> observer)
599*6777b538SAndroid Build Coastguard Worker : observer(observer),
600*6777b538SAndroid Build Coastguard Worker task_runner(SequencedTaskRunner::GetCurrentDefault()) {}
601*6777b538SAndroid Build Coastguard Worker ~RegisteredAsyncObserver() = default;
602*6777b538SAndroid Build Coastguard Worker
603*6777b538SAndroid Build Coastguard Worker WeakPtr<AsyncEnabledStateObserver> observer;
604*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner;
605*6777b538SAndroid Build Coastguard Worker };
606*6777b538SAndroid Build Coastguard Worker
TraceLogStatus()607*6777b538SAndroid Build Coastguard Worker TraceLogStatus::TraceLogStatus() : event_capacity(0), event_count(0) {}
608*6777b538SAndroid Build Coastguard Worker
609*6777b538SAndroid Build Coastguard Worker TraceLogStatus::~TraceLogStatus() = default;
610*6777b538SAndroid Build Coastguard Worker
611*6777b538SAndroid Build Coastguard Worker // static
GetInstance()612*6777b538SAndroid Build Coastguard Worker TraceLog* TraceLog::GetInstance() {
613*6777b538SAndroid Build Coastguard Worker static base::NoDestructor<TraceLog> instance(0);
614*6777b538SAndroid Build Coastguard Worker return instance.get();
615*6777b538SAndroid Build Coastguard Worker }
616*6777b538SAndroid Build Coastguard Worker
617*6777b538SAndroid Build Coastguard Worker // static
ResetForTesting()618*6777b538SAndroid Build Coastguard Worker void TraceLog::ResetForTesting() {
619*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
620*6777b538SAndroid Build Coastguard Worker auto* self = GetInstance();
621*6777b538SAndroid Build Coastguard Worker AutoLock lock(self->observers_lock_);
622*6777b538SAndroid Build Coastguard Worker self->enabled_state_observers_.clear();
623*6777b538SAndroid Build Coastguard Worker self->owned_enabled_state_observer_copy_.clear();
624*6777b538SAndroid Build Coastguard Worker self->async_observers_.clear();
625*6777b538SAndroid Build Coastguard Worker self->InitializePerfettoIfNeeded();
626*6777b538SAndroid Build Coastguard Worker #else // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
627*6777b538SAndroid Build Coastguard Worker if (!g_trace_log_for_testing)
628*6777b538SAndroid Build Coastguard Worker return;
629*6777b538SAndroid Build Coastguard Worker {
630*6777b538SAndroid Build Coastguard Worker AutoLock lock(g_trace_log_for_testing->lock_);
631*6777b538SAndroid Build Coastguard Worker CategoryRegistry::ResetForTesting();
632*6777b538SAndroid Build Coastguard Worker }
633*6777b538SAndroid Build Coastguard Worker // Don't reset the generation value back to 0. TraceLog is normally
634*6777b538SAndroid Build Coastguard Worker // supposed to be a singleton and the value of generation is never
635*6777b538SAndroid Build Coastguard Worker // supposed to decrease.
636*6777b538SAndroid Build Coastguard Worker const int generation = g_trace_log_for_testing->generation() + 1;
637*6777b538SAndroid Build Coastguard Worker g_trace_log_for_testing->~TraceLog();
638*6777b538SAndroid Build Coastguard Worker new (g_trace_log_for_testing) TraceLog(generation);
639*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
640*6777b538SAndroid Build Coastguard Worker }
641*6777b538SAndroid Build Coastguard Worker
TraceLog(int generation)642*6777b538SAndroid Build Coastguard Worker TraceLog::TraceLog(int generation)
643*6777b538SAndroid Build Coastguard Worker : process_sort_index_(0),
644*6777b538SAndroid Build Coastguard Worker process_id_hash_(0),
645*6777b538SAndroid Build Coastguard Worker process_id_(base::kNullProcessId),
646*6777b538SAndroid Build Coastguard Worker trace_options_(kInternalRecordUntilFull),
647*6777b538SAndroid Build Coastguard Worker trace_config_(TraceConfig()),
648*6777b538SAndroid Build Coastguard Worker thread_shared_chunk_index_(0),
649*6777b538SAndroid Build Coastguard Worker generation_(generation),
650*6777b538SAndroid Build Coastguard Worker use_worker_thread_(false) {
651*6777b538SAndroid Build Coastguard Worker CategoryRegistry::Initialize();
652*6777b538SAndroid Build Coastguard Worker
653*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_NACL) // NaCl shouldn't expose the process id.
654*6777b538SAndroid Build Coastguard Worker SetProcessID(0);
655*6777b538SAndroid Build Coastguard Worker #else
656*6777b538SAndroid Build Coastguard Worker SetProcessID(GetCurrentProcId());
657*6777b538SAndroid Build Coastguard Worker #endif
658*6777b538SAndroid Build Coastguard Worker
659*6777b538SAndroid Build Coastguard Worker logged_events_.reset(CreateTraceBuffer());
660*6777b538SAndroid Build Coastguard Worker
661*6777b538SAndroid Build Coastguard Worker MemoryDumpManager::GetInstance()->RegisterDumpProvider(this, "TraceLog",
662*6777b538SAndroid Build Coastguard Worker nullptr);
663*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
664*6777b538SAndroid Build Coastguard Worker TrackEvent::AddSessionObserver(this);
665*6777b538SAndroid Build Coastguard Worker // When using the Perfetto client library, TRACE_EVENT macros will bypass
666*6777b538SAndroid Build Coastguard Worker // TraceLog entirely. However, trace event embedders which haven't been ported
667*6777b538SAndroid Build Coastguard Worker // to Perfetto yet will still be using TRACE_EVENT_API_ADD_TRACE_EVENT, so we
668*6777b538SAndroid Build Coastguard Worker // need to route these events to Perfetto using an override here. This
669*6777b538SAndroid Build Coastguard Worker // override is also used to capture internal metadata events.
670*6777b538SAndroid Build Coastguard Worker SetAddTraceEventOverrides(&OnAddLegacyTraceEvent, nullptr,
671*6777b538SAndroid Build Coastguard Worker &OnUpdateLegacyTraceEventDuration);
672*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
673*6777b538SAndroid Build Coastguard Worker g_trace_log_for_testing = this;
674*6777b538SAndroid Build Coastguard Worker }
675*6777b538SAndroid Build Coastguard Worker
~TraceLog()676*6777b538SAndroid Build Coastguard Worker TraceLog::~TraceLog() {
677*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
678*6777b538SAndroid Build Coastguard Worker TrackEvent::RemoveSessionObserver(this);
679*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
680*6777b538SAndroid Build Coastguard Worker }
681*6777b538SAndroid Build Coastguard Worker
InitializeThreadLocalEventBufferIfSupported()682*6777b538SAndroid Build Coastguard Worker void TraceLog::InitializeThreadLocalEventBufferIfSupported() {
683*6777b538SAndroid Build Coastguard Worker // A ThreadLocalEventBuffer needs the message loop with a task runner
684*6777b538SAndroid Build Coastguard Worker // - to know when the thread exits;
685*6777b538SAndroid Build Coastguard Worker // - to handle the final flush.
686*6777b538SAndroid Build Coastguard Worker // For a thread without a message loop or if the message loop may be blocked,
687*6777b538SAndroid Build Coastguard Worker // the trace events will be added into the main buffer directly.
688*6777b538SAndroid Build Coastguard Worker if (thread_blocks_message_loop || !CurrentThread::IsSet() ||
689*6777b538SAndroid Build Coastguard Worker !SingleThreadTaskRunner::HasCurrentDefault()) {
690*6777b538SAndroid Build Coastguard Worker return;
691*6777b538SAndroid Build Coastguard Worker }
692*6777b538SAndroid Build Coastguard Worker HEAP_PROFILER_SCOPED_IGNORE;
693*6777b538SAndroid Build Coastguard Worker if (thread_local_event_buffer &&
694*6777b538SAndroid Build Coastguard Worker !CheckGeneration(thread_local_event_buffer->generation())) {
695*6777b538SAndroid Build Coastguard Worker delete thread_local_event_buffer;
696*6777b538SAndroid Build Coastguard Worker }
697*6777b538SAndroid Build Coastguard Worker if (!thread_local_event_buffer) {
698*6777b538SAndroid Build Coastguard Worker thread_local_event_buffer = new ThreadLocalEventBuffer(this);
699*6777b538SAndroid Build Coastguard Worker }
700*6777b538SAndroid Build Coastguard Worker }
701*6777b538SAndroid Build Coastguard Worker
OnMemoryDump(const MemoryDumpArgs & args,ProcessMemoryDump * pmd)702*6777b538SAndroid Build Coastguard Worker bool TraceLog::OnMemoryDump(const MemoryDumpArgs& args,
703*6777b538SAndroid Build Coastguard Worker ProcessMemoryDump* pmd) {
704*6777b538SAndroid Build Coastguard Worker // TODO(ssid): Use MemoryDumpArgs to create light dumps when requested
705*6777b538SAndroid Build Coastguard Worker // (crbug.com/499731).
706*6777b538SAndroid Build Coastguard Worker TraceEventMemoryOverhead overhead;
707*6777b538SAndroid Build Coastguard Worker overhead.Add(TraceEventMemoryOverhead::kOther, sizeof(*this));
708*6777b538SAndroid Build Coastguard Worker {
709*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
710*6777b538SAndroid Build Coastguard Worker if (logged_events_)
711*6777b538SAndroid Build Coastguard Worker logged_events_->EstimateTraceMemoryOverhead(&overhead);
712*6777b538SAndroid Build Coastguard Worker
713*6777b538SAndroid Build Coastguard Worker for (auto& metadata_event : metadata_events_)
714*6777b538SAndroid Build Coastguard Worker metadata_event->EstimateTraceMemoryOverhead(&overhead);
715*6777b538SAndroid Build Coastguard Worker }
716*6777b538SAndroid Build Coastguard Worker overhead.AddSelf();
717*6777b538SAndroid Build Coastguard Worker overhead.DumpInto("tracing/main_trace_log", pmd);
718*6777b538SAndroid Build Coastguard Worker return true;
719*6777b538SAndroid Build Coastguard Worker }
720*6777b538SAndroid Build Coastguard Worker
GetCategoryGroupEnabled(const char * category_group)721*6777b538SAndroid Build Coastguard Worker const unsigned char* TraceLog::GetCategoryGroupEnabled(
722*6777b538SAndroid Build Coastguard Worker const char* category_group) {
723*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
724*6777b538SAndroid Build Coastguard Worker return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group);
725*6777b538SAndroid Build Coastguard Worker #else // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
726*6777b538SAndroid Build Coastguard Worker TraceLog* tracelog = GetInstance();
727*6777b538SAndroid Build Coastguard Worker if (!tracelog) {
728*6777b538SAndroid Build Coastguard Worker DCHECK(!CategoryRegistry::kCategoryAlreadyShutdown->is_enabled());
729*6777b538SAndroid Build Coastguard Worker return CategoryRegistry::kCategoryAlreadyShutdown->state_ptr();
730*6777b538SAndroid Build Coastguard Worker }
731*6777b538SAndroid Build Coastguard Worker TraceCategory* category = CategoryRegistry::GetCategoryByName(category_group);
732*6777b538SAndroid Build Coastguard Worker if (!category) {
733*6777b538SAndroid Build Coastguard Worker // Slow path: in the case of a new category we have to repeat the check
734*6777b538SAndroid Build Coastguard Worker // holding the lock, as multiple threads might have reached this point
735*6777b538SAndroid Build Coastguard Worker // at the same time.
736*6777b538SAndroid Build Coastguard Worker auto category_initializer = [](TraceCategory* category) {
737*6777b538SAndroid Build Coastguard Worker TraceLog::GetInstance()->UpdateCategoryState(category);
738*6777b538SAndroid Build Coastguard Worker };
739*6777b538SAndroid Build Coastguard Worker AutoLock lock(tracelog->lock_);
740*6777b538SAndroid Build Coastguard Worker CategoryRegistry::GetOrCreateCategoryLocked(
741*6777b538SAndroid Build Coastguard Worker category_group, category_initializer, &category);
742*6777b538SAndroid Build Coastguard Worker }
743*6777b538SAndroid Build Coastguard Worker DCHECK(category->state_ptr());
744*6777b538SAndroid Build Coastguard Worker return category->state_ptr();
745*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
746*6777b538SAndroid Build Coastguard Worker }
747*6777b538SAndroid Build Coastguard Worker
GetCategoryGroupName(const unsigned char * category_group_enabled)748*6777b538SAndroid Build Coastguard Worker const char* TraceLog::GetCategoryGroupName(
749*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled) {
750*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
751*6777b538SAndroid Build Coastguard Worker return TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(category_group_enabled);
752*6777b538SAndroid Build Coastguard Worker #else // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
753*6777b538SAndroid Build Coastguard Worker return CategoryRegistry::GetCategoryByStatePtr(category_group_enabled)
754*6777b538SAndroid Build Coastguard Worker ->name();
755*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
756*6777b538SAndroid Build Coastguard Worker }
757*6777b538SAndroid Build Coastguard Worker
UpdateCategoryState(TraceCategory * category)758*6777b538SAndroid Build Coastguard Worker void TraceLog::UpdateCategoryState(TraceCategory* category) {
759*6777b538SAndroid Build Coastguard Worker lock_.AssertAcquired();
760*6777b538SAndroid Build Coastguard Worker DCHECK(category->is_valid());
761*6777b538SAndroid Build Coastguard Worker unsigned char state_flags = 0;
762*6777b538SAndroid Build Coastguard Worker if (enabled_ && trace_config_.IsCategoryGroupEnabled(category->name())) {
763*6777b538SAndroid Build Coastguard Worker state_flags |= TraceCategory::ENABLED_FOR_RECORDING;
764*6777b538SAndroid Build Coastguard Worker }
765*6777b538SAndroid Build Coastguard Worker
766*6777b538SAndroid Build Coastguard Worker // TODO(primiano): this is a temporary workaround for catapult:#2341,
767*6777b538SAndroid Build Coastguard Worker // to guarantee that metadata events are always added even if the category
768*6777b538SAndroid Build Coastguard Worker // filter is "-*". See crbug.com/618054 for more details and long-term fix.
769*6777b538SAndroid Build Coastguard Worker if (enabled_ && category == CategoryRegistry::kCategoryMetadata) {
770*6777b538SAndroid Build Coastguard Worker state_flags |= TraceCategory::ENABLED_FOR_RECORDING;
771*6777b538SAndroid Build Coastguard Worker }
772*6777b538SAndroid Build Coastguard Worker
773*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
774*6777b538SAndroid Build Coastguard Worker if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled(
775*6777b538SAndroid Build Coastguard Worker category->name())) {
776*6777b538SAndroid Build Coastguard Worker state_flags |= TraceCategory::ENABLED_FOR_ETW_EXPORT;
777*6777b538SAndroid Build Coastguard Worker }
778*6777b538SAndroid Build Coastguard Worker #endif
779*6777b538SAndroid Build Coastguard Worker
780*6777b538SAndroid Build Coastguard Worker category->set_state(state_flags);
781*6777b538SAndroid Build Coastguard Worker }
782*6777b538SAndroid Build Coastguard Worker
UpdateCategoryRegistry()783*6777b538SAndroid Build Coastguard Worker void TraceLog::UpdateCategoryRegistry() {
784*6777b538SAndroid Build Coastguard Worker lock_.AssertAcquired();
785*6777b538SAndroid Build Coastguard Worker for (TraceCategory& category : CategoryRegistry::GetAllCategories()) {
786*6777b538SAndroid Build Coastguard Worker UpdateCategoryState(&category);
787*6777b538SAndroid Build Coastguard Worker }
788*6777b538SAndroid Build Coastguard Worker }
789*6777b538SAndroid Build Coastguard Worker
SetEnabled(const TraceConfig & trace_config,uint8_t modes_to_enable)790*6777b538SAndroid Build Coastguard Worker void TraceLog::SetEnabled(const TraceConfig& trace_config,
791*6777b538SAndroid Build Coastguard Worker uint8_t modes_to_enable) {
792*6777b538SAndroid Build Coastguard Worker // FILTERING_MODE is no longer supported.
793*6777b538SAndroid Build Coastguard Worker DCHECK(modes_to_enable == RECORDING_MODE);
794*6777b538SAndroid Build Coastguard Worker DCHECK(trace_config.process_filter_config().IsEnabled(process_id_));
795*6777b538SAndroid Build Coastguard Worker
796*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
797*6777b538SAndroid Build Coastguard Worker
798*6777b538SAndroid Build Coastguard Worker // Perfetto only supports basic wildcard filtering, so check that we're not
799*6777b538SAndroid Build Coastguard Worker // trying to use more complex filters.
800*6777b538SAndroid Build Coastguard Worker for (const auto& excluded :
801*6777b538SAndroid Build Coastguard Worker trace_config.category_filter().excluded_categories()) {
802*6777b538SAndroid Build Coastguard Worker DCHECK(excluded.find("?") == std::string::npos);
803*6777b538SAndroid Build Coastguard Worker DCHECK(excluded.find("*") == std::string::npos ||
804*6777b538SAndroid Build Coastguard Worker excluded.find("*") == excluded.size() - 1);
805*6777b538SAndroid Build Coastguard Worker }
806*6777b538SAndroid Build Coastguard Worker for (const auto& included :
807*6777b538SAndroid Build Coastguard Worker trace_config.category_filter().included_categories()) {
808*6777b538SAndroid Build Coastguard Worker DCHECK(included.find("?") == std::string::npos);
809*6777b538SAndroid Build Coastguard Worker DCHECK(included.find("*") == std::string::npos ||
810*6777b538SAndroid Build Coastguard Worker included.find("*") == included.size() - 1);
811*6777b538SAndroid Build Coastguard Worker }
812*6777b538SAndroid Build Coastguard Worker for (const auto& disabled :
813*6777b538SAndroid Build Coastguard Worker trace_config.category_filter().disabled_categories()) {
814*6777b538SAndroid Build Coastguard Worker DCHECK(disabled.find("?") == std::string::npos);
815*6777b538SAndroid Build Coastguard Worker DCHECK(disabled.find("*") == std::string::npos ||
816*6777b538SAndroid Build Coastguard Worker disabled.find("*") == disabled.size() - 1);
817*6777b538SAndroid Build Coastguard Worker }
818*6777b538SAndroid Build Coastguard Worker
819*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
820*6777b538SAndroid Build Coastguard Worker DCHECK(!trace_config.IsArgumentFilterEnabled());
821*6777b538SAndroid Build Coastguard Worker
822*6777b538SAndroid Build Coastguard Worker // TODO(khokhlov): Avoid duplication between this code and
823*6777b538SAndroid Build Coastguard Worker // services/tracing/public/cpp/perfetto/perfetto_config.cc.
824*6777b538SAndroid Build Coastguard Worker perfetto::TraceConfig perfetto_config;
825*6777b538SAndroid Build Coastguard Worker size_t size_limit = trace_config.GetTraceBufferSizeInKb();
826*6777b538SAndroid Build Coastguard Worker if (size_limit == 0)
827*6777b538SAndroid Build Coastguard Worker size_limit = 200 * 1024;
828*6777b538SAndroid Build Coastguard Worker auto* buffer_config = perfetto_config.add_buffers();
829*6777b538SAndroid Build Coastguard Worker buffer_config->set_size_kb(checked_cast<uint32_t>(size_limit));
830*6777b538SAndroid Build Coastguard Worker switch (trace_config.GetTraceRecordMode()) {
831*6777b538SAndroid Build Coastguard Worker case base::trace_event::RECORD_UNTIL_FULL:
832*6777b538SAndroid Build Coastguard Worker case base::trace_event::RECORD_AS_MUCH_AS_POSSIBLE:
833*6777b538SAndroid Build Coastguard Worker buffer_config->set_fill_policy(
834*6777b538SAndroid Build Coastguard Worker perfetto::TraceConfig::BufferConfig::DISCARD);
835*6777b538SAndroid Build Coastguard Worker break;
836*6777b538SAndroid Build Coastguard Worker case base::trace_event::RECORD_CONTINUOUSLY:
837*6777b538SAndroid Build Coastguard Worker buffer_config->set_fill_policy(
838*6777b538SAndroid Build Coastguard Worker perfetto::TraceConfig::BufferConfig::RING_BUFFER);
839*6777b538SAndroid Build Coastguard Worker break;
840*6777b538SAndroid Build Coastguard Worker case base::trace_event::ECHO_TO_CONSOLE:
841*6777b538SAndroid Build Coastguard Worker // Handled below.
842*6777b538SAndroid Build Coastguard Worker break;
843*6777b538SAndroid Build Coastguard Worker }
844*6777b538SAndroid Build Coastguard Worker
845*6777b538SAndroid Build Coastguard Worker // Add the track event data source.
846*6777b538SAndroid Build Coastguard Worker // TODO(skyostil): Configure kTraceClockId as the primary trace clock.
847*6777b538SAndroid Build Coastguard Worker auto* data_source = perfetto_config.add_data_sources();
848*6777b538SAndroid Build Coastguard Worker auto* source_config = data_source->mutable_config();
849*6777b538SAndroid Build Coastguard Worker source_config->set_name("track_event");
850*6777b538SAndroid Build Coastguard Worker source_config->set_target_buffer(0);
851*6777b538SAndroid Build Coastguard Worker auto* source_chrome_config = source_config->mutable_chrome_config();
852*6777b538SAndroid Build Coastguard Worker source_chrome_config->set_trace_config(trace_config.ToString());
853*6777b538SAndroid Build Coastguard Worker source_chrome_config->set_convert_to_legacy_json(true);
854*6777b538SAndroid Build Coastguard Worker
855*6777b538SAndroid Build Coastguard Worker if (trace_config.GetTraceRecordMode() == base::trace_event::ECHO_TO_CONSOLE) {
856*6777b538SAndroid Build Coastguard Worker perfetto::ConsoleInterceptor::Register();
857*6777b538SAndroid Build Coastguard Worker source_config->mutable_interceptor_config()->set_name("console");
858*6777b538SAndroid Build Coastguard Worker }
859*6777b538SAndroid Build Coastguard Worker
860*6777b538SAndroid Build Coastguard Worker source_config->set_track_event_config_raw(
861*6777b538SAndroid Build Coastguard Worker trace_config.ToPerfettoTrackEventConfigRaw(
862*6777b538SAndroid Build Coastguard Worker /*privacy_filtering_enabled = */ false));
863*6777b538SAndroid Build Coastguard Worker
864*6777b538SAndroid Build Coastguard Worker if (trace_config.IsCategoryGroupEnabled("disabled-by-default-memory-infra")) {
865*6777b538SAndroid Build Coastguard Worker data_source = perfetto_config.add_data_sources();
866*6777b538SAndroid Build Coastguard Worker source_config = data_source->mutable_config();
867*6777b538SAndroid Build Coastguard Worker source_config->set_name("org.chromium.memory_instrumentation");
868*6777b538SAndroid Build Coastguard Worker source_config->set_target_buffer(0);
869*6777b538SAndroid Build Coastguard Worker source_chrome_config = source_config->mutable_chrome_config();
870*6777b538SAndroid Build Coastguard Worker source_chrome_config->set_trace_config(trace_config.ToString());
871*6777b538SAndroid Build Coastguard Worker source_chrome_config->set_convert_to_legacy_json(true);
872*6777b538SAndroid Build Coastguard Worker }
873*6777b538SAndroid Build Coastguard Worker
874*6777b538SAndroid Build Coastguard Worker // Clear incremental state every 0.5 seconds, so that we lose at most the
875*6777b538SAndroid Build Coastguard Worker // first 0.5 seconds of the trace (if we wrap around Perfetto's central
876*6777b538SAndroid Build Coastguard Worker // buffer).
877*6777b538SAndroid Build Coastguard Worker // This value strikes balance between minimizing interned data overhead, and
878*6777b538SAndroid Build Coastguard Worker // reducing the risk of data loss in ring buffer mode.
879*6777b538SAndroid Build Coastguard Worker perfetto_config.mutable_incremental_state_config()->set_clear_period_ms(500);
880*6777b538SAndroid Build Coastguard Worker
881*6777b538SAndroid Build Coastguard Worker SetEnabledImpl(trace_config, perfetto_config);
882*6777b538SAndroid Build Coastguard Worker #else // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
883*6777b538SAndroid Build Coastguard Worker // Can't enable tracing when Flush() is in progress.
884*6777b538SAndroid Build Coastguard Worker DCHECK(!flush_task_runner_);
885*6777b538SAndroid Build Coastguard Worker
886*6777b538SAndroid Build Coastguard Worker InternalTraceOptions new_options =
887*6777b538SAndroid Build Coastguard Worker GetInternalOptionsFromTraceConfig(trace_config);
888*6777b538SAndroid Build Coastguard Worker
889*6777b538SAndroid Build Coastguard Worker InternalTraceOptions old_options = trace_options();
890*6777b538SAndroid Build Coastguard Worker
891*6777b538SAndroid Build Coastguard Worker if (dispatching_to_observers_) {
892*6777b538SAndroid Build Coastguard Worker // TODO(ssid): Change to NOTREACHED after fixing crbug.com/625170.
893*6777b538SAndroid Build Coastguard Worker DLOG(ERROR)
894*6777b538SAndroid Build Coastguard Worker << "Cannot manipulate TraceLog::Enabled state from an observer.";
895*6777b538SAndroid Build Coastguard Worker return;
896*6777b538SAndroid Build Coastguard Worker }
897*6777b538SAndroid Build Coastguard Worker
898*6777b538SAndroid Build Coastguard Worker // Update trace config for recording.
899*6777b538SAndroid Build Coastguard Worker const bool already_recording = enabled_;
900*6777b538SAndroid Build Coastguard Worker if (already_recording) {
901*6777b538SAndroid Build Coastguard Worker trace_config_.Merge(trace_config);
902*6777b538SAndroid Build Coastguard Worker } else {
903*6777b538SAndroid Build Coastguard Worker trace_config_ = trace_config;
904*6777b538SAndroid Build Coastguard Worker }
905*6777b538SAndroid Build Coastguard Worker
906*6777b538SAndroid Build Coastguard Worker enabled_ = true;
907*6777b538SAndroid Build Coastguard Worker UpdateCategoryRegistry();
908*6777b538SAndroid Build Coastguard Worker
909*6777b538SAndroid Build Coastguard Worker // Do not notify observers or create trace buffer if only enabled for
910*6777b538SAndroid Build Coastguard Worker // filtering or if recording was already enabled.
911*6777b538SAndroid Build Coastguard Worker if (already_recording)
912*6777b538SAndroid Build Coastguard Worker return;
913*6777b538SAndroid Build Coastguard Worker
914*6777b538SAndroid Build Coastguard Worker // Discard events if new trace options are different. Reducing trace buffer
915*6777b538SAndroid Build Coastguard Worker // size is not supported while already recording, so only replace trace
916*6777b538SAndroid Build Coastguard Worker // buffer if we were not already recording.
917*6777b538SAndroid Build Coastguard Worker if (new_options != old_options ||
918*6777b538SAndroid Build Coastguard Worker (trace_config_.GetTraceBufferSizeInEvents() && !already_recording)) {
919*6777b538SAndroid Build Coastguard Worker trace_options_.store(new_options, std::memory_order_relaxed);
920*6777b538SAndroid Build Coastguard Worker UseNextTraceBuffer();
921*6777b538SAndroid Build Coastguard Worker }
922*6777b538SAndroid Build Coastguard Worker
923*6777b538SAndroid Build Coastguard Worker num_traces_recorded_++;
924*6777b538SAndroid Build Coastguard Worker
925*6777b538SAndroid Build Coastguard Worker UpdateCategoryRegistry();
926*6777b538SAndroid Build Coastguard Worker
927*6777b538SAndroid Build Coastguard Worker dispatching_to_observers_ = true;
928*6777b538SAndroid Build Coastguard Worker {
929*6777b538SAndroid Build Coastguard Worker // Notify observers outside of the thread events lock, so they can trigger
930*6777b538SAndroid Build Coastguard Worker // trace events.
931*6777b538SAndroid Build Coastguard Worker AutoUnlock unlock(lock_);
932*6777b538SAndroid Build Coastguard Worker AutoLock lock2(observers_lock_);
933*6777b538SAndroid Build Coastguard Worker for (EnabledStateObserver* observer : enabled_state_observers_)
934*6777b538SAndroid Build Coastguard Worker observer->OnTraceLogEnabled();
935*6777b538SAndroid Build Coastguard Worker for (const auto& it : async_observers_) {
936*6777b538SAndroid Build Coastguard Worker it.second.task_runner->PostTask(
937*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&AsyncEnabledStateObserver::OnTraceLogEnabled,
938*6777b538SAndroid Build Coastguard Worker it.second.observer));
939*6777b538SAndroid Build Coastguard Worker }
940*6777b538SAndroid Build Coastguard Worker }
941*6777b538SAndroid Build Coastguard Worker dispatching_to_observers_ = false;
942*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
943*6777b538SAndroid Build Coastguard Worker }
944*6777b538SAndroid Build Coastguard Worker
945*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
GetCurrentTrackEventDataSourceConfig() const946*6777b538SAndroid Build Coastguard Worker perfetto::DataSourceConfig TraceLog::GetCurrentTrackEventDataSourceConfig()
947*6777b538SAndroid Build Coastguard Worker const {
948*6777b538SAndroid Build Coastguard Worker AutoLock lock(track_event_lock_);
949*6777b538SAndroid Build Coastguard Worker if (track_event_sessions_.empty()) {
950*6777b538SAndroid Build Coastguard Worker return perfetto::DataSourceConfig();
951*6777b538SAndroid Build Coastguard Worker }
952*6777b538SAndroid Build Coastguard Worker return track_event_sessions_[0].config;
953*6777b538SAndroid Build Coastguard Worker }
954*6777b538SAndroid Build Coastguard Worker
InitializePerfettoIfNeeded()955*6777b538SAndroid Build Coastguard Worker void TraceLog::InitializePerfettoIfNeeded() {
956*6777b538SAndroid Build Coastguard Worker // When we're using the Perfetto client library, only tests should be
957*6777b538SAndroid Build Coastguard Worker // recording traces directly through TraceLog. Production code should instead
958*6777b538SAndroid Build Coastguard Worker // use perfetto::Tracing::NewTrace(). Let's make sure the tracing service
959*6777b538SAndroid Build Coastguard Worker // didn't already initialize Perfetto in this process, because it's not safe
960*6777b538SAndroid Build Coastguard Worker // to consume trace data from arbitrary processes through TraceLog as the JSON
961*6777b538SAndroid Build Coastguard Worker // conversion here isn't sandboxed like with the real tracing service.
962*6777b538SAndroid Build Coastguard Worker //
963*6777b538SAndroid Build Coastguard Worker // Note that initializing Perfetto here requires the thread pool to be ready.
964*6777b538SAndroid Build Coastguard Worker CHECK(!perfetto::Tracing::IsInitialized() ||
965*6777b538SAndroid Build Coastguard Worker g_perfetto_initialized_by_tracelog)
966*6777b538SAndroid Build Coastguard Worker << "Don't use TraceLog for recording traces from non-test code. Use "
967*6777b538SAndroid Build Coastguard Worker "perfetto::Tracing::NewTrace() instead.";
968*6777b538SAndroid Build Coastguard Worker
969*6777b538SAndroid Build Coastguard Worker if (perfetto::Tracing::IsInitialized())
970*6777b538SAndroid Build Coastguard Worker return;
971*6777b538SAndroid Build Coastguard Worker g_perfetto_initialized_by_tracelog = true;
972*6777b538SAndroid Build Coastguard Worker perfetto::TracingInitArgs init_args;
973*6777b538SAndroid Build Coastguard Worker init_args.backends = perfetto::BackendType::kInProcessBackend;
974*6777b538SAndroid Build Coastguard Worker init_args.shmem_batch_commits_duration_ms = 1000;
975*6777b538SAndroid Build Coastguard Worker init_args.shmem_size_hint_kb = 4 * 1024;
976*6777b538SAndroid Build Coastguard Worker init_args.shmem_direct_patching_enabled = true;
977*6777b538SAndroid Build Coastguard Worker init_args.disallow_merging_with_system_tracks = true;
978*6777b538SAndroid Build Coastguard Worker perfetto::Tracing::Initialize(init_args);
979*6777b538SAndroid Build Coastguard Worker TrackEvent::Register();
980*6777b538SAndroid Build Coastguard Worker }
981*6777b538SAndroid Build Coastguard Worker
IsPerfettoInitializedByTraceLog() const982*6777b538SAndroid Build Coastguard Worker bool TraceLog::IsPerfettoInitializedByTraceLog() const {
983*6777b538SAndroid Build Coastguard Worker return g_perfetto_initialized_by_tracelog;
984*6777b538SAndroid Build Coastguard Worker }
985*6777b538SAndroid Build Coastguard Worker
SetEnabled(const TraceConfig & trace_config,const perfetto::TraceConfig & perfetto_config)986*6777b538SAndroid Build Coastguard Worker void TraceLog::SetEnabled(const TraceConfig& trace_config,
987*6777b538SAndroid Build Coastguard Worker const perfetto::TraceConfig& perfetto_config) {
988*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
989*6777b538SAndroid Build Coastguard Worker SetEnabledImpl(trace_config, perfetto_config);
990*6777b538SAndroid Build Coastguard Worker }
991*6777b538SAndroid Build Coastguard Worker
SetEnabledImpl(const TraceConfig & trace_config,const perfetto::TraceConfig & perfetto_config)992*6777b538SAndroid Build Coastguard Worker void TraceLog::SetEnabledImpl(const TraceConfig& trace_config,
993*6777b538SAndroid Build Coastguard Worker const perfetto::TraceConfig& perfetto_config) {
994*6777b538SAndroid Build Coastguard Worker DCHECK(!TrackEvent::IsEnabled());
995*6777b538SAndroid Build Coastguard Worker lock_.AssertAcquired();
996*6777b538SAndroid Build Coastguard Worker InitializePerfettoIfNeeded();
997*6777b538SAndroid Build Coastguard Worker trace_config_ = trace_config;
998*6777b538SAndroid Build Coastguard Worker perfetto_config_ = perfetto_config;
999*6777b538SAndroid Build Coastguard Worker tracing_session_ = perfetto::Tracing::NewTrace();
1000*6777b538SAndroid Build Coastguard Worker
1001*6777b538SAndroid Build Coastguard Worker AutoUnlock unlock(lock_);
1002*6777b538SAndroid Build Coastguard Worker tracing_session_->Setup(perfetto_config);
1003*6777b538SAndroid Build Coastguard Worker tracing_session_->StartBlocking();
1004*6777b538SAndroid Build Coastguard Worker }
1005*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
1006*6777b538SAndroid Build Coastguard Worker
SetArgumentFilterPredicate(const ArgumentFilterPredicate & argument_filter_predicate)1007*6777b538SAndroid Build Coastguard Worker void TraceLog::SetArgumentFilterPredicate(
1008*6777b538SAndroid Build Coastguard Worker const ArgumentFilterPredicate& argument_filter_predicate) {
1009*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1010*6777b538SAndroid Build Coastguard Worker DCHECK(!argument_filter_predicate.is_null());
1011*6777b538SAndroid Build Coastguard Worker // Replace the existing argument filter.
1012*6777b538SAndroid Build Coastguard Worker argument_filter_predicate_ = argument_filter_predicate;
1013*6777b538SAndroid Build Coastguard Worker }
1014*6777b538SAndroid Build Coastguard Worker
GetArgumentFilterPredicate() const1015*6777b538SAndroid Build Coastguard Worker ArgumentFilterPredicate TraceLog::GetArgumentFilterPredicate() const {
1016*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1017*6777b538SAndroid Build Coastguard Worker return argument_filter_predicate_;
1018*6777b538SAndroid Build Coastguard Worker }
1019*6777b538SAndroid Build Coastguard Worker
SetMetadataFilterPredicate(const MetadataFilterPredicate & metadata_filter_predicate)1020*6777b538SAndroid Build Coastguard Worker void TraceLog::SetMetadataFilterPredicate(
1021*6777b538SAndroid Build Coastguard Worker const MetadataFilterPredicate& metadata_filter_predicate) {
1022*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1023*6777b538SAndroid Build Coastguard Worker DCHECK(!metadata_filter_predicate.is_null());
1024*6777b538SAndroid Build Coastguard Worker // Replace the existing argument filter.
1025*6777b538SAndroid Build Coastguard Worker metadata_filter_predicate_ = metadata_filter_predicate;
1026*6777b538SAndroid Build Coastguard Worker }
1027*6777b538SAndroid Build Coastguard Worker
GetMetadataFilterPredicate() const1028*6777b538SAndroid Build Coastguard Worker MetadataFilterPredicate TraceLog::GetMetadataFilterPredicate() const {
1029*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1030*6777b538SAndroid Build Coastguard Worker return metadata_filter_predicate_;
1031*6777b538SAndroid Build Coastguard Worker }
1032*6777b538SAndroid Build Coastguard Worker
SetRecordHostAppPackageName(bool record_host_app_package_name)1033*6777b538SAndroid Build Coastguard Worker void TraceLog::SetRecordHostAppPackageName(bool record_host_app_package_name) {
1034*6777b538SAndroid Build Coastguard Worker record_host_app_package_name_ = record_host_app_package_name;
1035*6777b538SAndroid Build Coastguard Worker }
1036*6777b538SAndroid Build Coastguard Worker
ShouldRecordHostAppPackageName() const1037*6777b538SAndroid Build Coastguard Worker bool TraceLog::ShouldRecordHostAppPackageName() const {
1038*6777b538SAndroid Build Coastguard Worker return record_host_app_package_name_;
1039*6777b538SAndroid Build Coastguard Worker }
1040*6777b538SAndroid Build Coastguard Worker
GetInternalOptionsFromTraceConfig(const TraceConfig & config)1041*6777b538SAndroid Build Coastguard Worker TraceLog::InternalTraceOptions TraceLog::GetInternalOptionsFromTraceConfig(
1042*6777b538SAndroid Build Coastguard Worker const TraceConfig& config) {
1043*6777b538SAndroid Build Coastguard Worker InternalTraceOptions ret = config.IsArgumentFilterEnabled()
1044*6777b538SAndroid Build Coastguard Worker ? kInternalEnableArgumentFilter
1045*6777b538SAndroid Build Coastguard Worker : kInternalNone;
1046*6777b538SAndroid Build Coastguard Worker switch (config.GetTraceRecordMode()) {
1047*6777b538SAndroid Build Coastguard Worker case RECORD_UNTIL_FULL:
1048*6777b538SAndroid Build Coastguard Worker return ret | kInternalRecordUntilFull;
1049*6777b538SAndroid Build Coastguard Worker case RECORD_CONTINUOUSLY:
1050*6777b538SAndroid Build Coastguard Worker return ret | kInternalRecordContinuously;
1051*6777b538SAndroid Build Coastguard Worker case ECHO_TO_CONSOLE:
1052*6777b538SAndroid Build Coastguard Worker return ret | kInternalEchoToConsole;
1053*6777b538SAndroid Build Coastguard Worker case RECORD_AS_MUCH_AS_POSSIBLE:
1054*6777b538SAndroid Build Coastguard Worker return ret | kInternalRecordAsMuchAsPossible;
1055*6777b538SAndroid Build Coastguard Worker }
1056*6777b538SAndroid Build Coastguard Worker NOTREACHED();
1057*6777b538SAndroid Build Coastguard Worker return kInternalNone;
1058*6777b538SAndroid Build Coastguard Worker }
1059*6777b538SAndroid Build Coastguard Worker
GetCurrentTraceConfig() const1060*6777b538SAndroid Build Coastguard Worker TraceConfig TraceLog::GetCurrentTraceConfig() const {
1061*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
1062*6777b538SAndroid Build Coastguard Worker const auto chrome_config =
1063*6777b538SAndroid Build Coastguard Worker GetCurrentTrackEventDataSourceConfig().chrome_config();
1064*6777b538SAndroid Build Coastguard Worker return TraceConfig(chrome_config.trace_config());
1065*6777b538SAndroid Build Coastguard Worker #else // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
1066*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1067*6777b538SAndroid Build Coastguard Worker return trace_config_;
1068*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
1069*6777b538SAndroid Build Coastguard Worker }
1070*6777b538SAndroid Build Coastguard Worker
SetDisabled()1071*6777b538SAndroid Build Coastguard Worker void TraceLog::SetDisabled() {
1072*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1073*6777b538SAndroid Build Coastguard Worker SetDisabledWhileLocked(RECORDING_MODE);
1074*6777b538SAndroid Build Coastguard Worker }
1075*6777b538SAndroid Build Coastguard Worker
SetDisabled(uint8_t modes_to_disable)1076*6777b538SAndroid Build Coastguard Worker void TraceLog::SetDisabled(uint8_t modes_to_disable) {
1077*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1078*6777b538SAndroid Build Coastguard Worker SetDisabledWhileLocked(modes_to_disable);
1079*6777b538SAndroid Build Coastguard Worker }
1080*6777b538SAndroid Build Coastguard Worker
SetDisabledWhileLocked(uint8_t modes_to_disable)1081*6777b538SAndroid Build Coastguard Worker void TraceLog::SetDisabledWhileLocked(uint8_t modes_to_disable) {
1082*6777b538SAndroid Build Coastguard Worker DCHECK(modes_to_disable == RECORDING_MODE);
1083*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
1084*6777b538SAndroid Build Coastguard Worker if (!tracing_session_)
1085*6777b538SAndroid Build Coastguard Worker return;
1086*6777b538SAndroid Build Coastguard Worker
1087*6777b538SAndroid Build Coastguard Worker AddMetadataEventsWhileLocked();
1088*6777b538SAndroid Build Coastguard Worker // Remove metadata events so they will not get added to a subsequent trace.
1089*6777b538SAndroid Build Coastguard Worker metadata_events_.clear();
1090*6777b538SAndroid Build Coastguard Worker
1091*6777b538SAndroid Build Coastguard Worker TrackEvent::Flush();
1092*6777b538SAndroid Build Coastguard Worker // If the current thread has an active task runner, allow nested tasks to run
1093*6777b538SAndroid Build Coastguard Worker // while stopping the session. This is needed by some tests, e.g., to allow
1094*6777b538SAndroid Build Coastguard Worker // data sources to properly flush themselves.
1095*6777b538SAndroid Build Coastguard Worker if (SingleThreadTaskRunner::HasCurrentDefault()) {
1096*6777b538SAndroid Build Coastguard Worker RunLoop stop_loop(RunLoop::Type::kNestableTasksAllowed);
1097*6777b538SAndroid Build Coastguard Worker auto quit_closure = stop_loop.QuitClosure();
1098*6777b538SAndroid Build Coastguard Worker tracing_session_->SetOnStopCallback(
1099*6777b538SAndroid Build Coastguard Worker [&quit_closure] { quit_closure.Run(); });
1100*6777b538SAndroid Build Coastguard Worker tracing_session_->Stop();
1101*6777b538SAndroid Build Coastguard Worker AutoUnlock unlock(lock_);
1102*6777b538SAndroid Build Coastguard Worker stop_loop.Run();
1103*6777b538SAndroid Build Coastguard Worker } else {
1104*6777b538SAndroid Build Coastguard Worker tracing_session_->StopBlocking();
1105*6777b538SAndroid Build Coastguard Worker }
1106*6777b538SAndroid Build Coastguard Worker #else // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
1107*6777b538SAndroid Build Coastguard Worker
1108*6777b538SAndroid Build Coastguard Worker if (dispatching_to_observers_) {
1109*6777b538SAndroid Build Coastguard Worker // TODO(ssid): Change to NOTREACHED after fixing crbug.com/625170.
1110*6777b538SAndroid Build Coastguard Worker DLOG(ERROR)
1111*6777b538SAndroid Build Coastguard Worker << "Cannot manipulate TraceLog::Enabled state from an observer.";
1112*6777b538SAndroid Build Coastguard Worker return;
1113*6777b538SAndroid Build Coastguard Worker }
1114*6777b538SAndroid Build Coastguard Worker
1115*6777b538SAndroid Build Coastguard Worker enabled_ = false;
1116*6777b538SAndroid Build Coastguard Worker trace_config_.Clear();
1117*6777b538SAndroid Build Coastguard Worker UpdateCategoryRegistry();
1118*6777b538SAndroid Build Coastguard Worker
1119*6777b538SAndroid Build Coastguard Worker AddMetadataEventsWhileLocked();
1120*6777b538SAndroid Build Coastguard Worker
1121*6777b538SAndroid Build Coastguard Worker // Remove metadata events so they will not get added to a subsequent trace.
1122*6777b538SAndroid Build Coastguard Worker metadata_events_.clear();
1123*6777b538SAndroid Build Coastguard Worker
1124*6777b538SAndroid Build Coastguard Worker dispatching_to_observers_ = true;
1125*6777b538SAndroid Build Coastguard Worker {
1126*6777b538SAndroid Build Coastguard Worker // Release trace events lock, so observers can trigger trace events.
1127*6777b538SAndroid Build Coastguard Worker AutoUnlock unlock(lock_);
1128*6777b538SAndroid Build Coastguard Worker AutoLock lock2(observers_lock_);
1129*6777b538SAndroid Build Coastguard Worker for (base::trace_event::TraceLog::EnabledStateObserver* it :
1130*6777b538SAndroid Build Coastguard Worker enabled_state_observers_) {
1131*6777b538SAndroid Build Coastguard Worker it->OnTraceLogDisabled();
1132*6777b538SAndroid Build Coastguard Worker }
1133*6777b538SAndroid Build Coastguard Worker for (const auto& it : async_observers_) {
1134*6777b538SAndroid Build Coastguard Worker it.second.task_runner->PostTask(
1135*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&AsyncEnabledStateObserver::OnTraceLogDisabled,
1136*6777b538SAndroid Build Coastguard Worker it.second.observer));
1137*6777b538SAndroid Build Coastguard Worker }
1138*6777b538SAndroid Build Coastguard Worker }
1139*6777b538SAndroid Build Coastguard Worker dispatching_to_observers_ = false;
1140*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
1141*6777b538SAndroid Build Coastguard Worker }
1142*6777b538SAndroid Build Coastguard Worker
GetNumTracesRecorded()1143*6777b538SAndroid Build Coastguard Worker int TraceLog::GetNumTracesRecorded() {
1144*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1145*6777b538SAndroid Build Coastguard Worker return enabled_ ? num_traces_recorded_ : -1;
1146*6777b538SAndroid Build Coastguard Worker }
1147*6777b538SAndroid Build Coastguard Worker
AddEnabledStateObserver(EnabledStateObserver * listener)1148*6777b538SAndroid Build Coastguard Worker void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) {
1149*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
1150*6777b538SAndroid Build Coastguard Worker enabled_state_observers_.push_back(listener);
1151*6777b538SAndroid Build Coastguard Worker }
1152*6777b538SAndroid Build Coastguard Worker
RemoveEnabledStateObserver(EnabledStateObserver * listener)1153*6777b538SAndroid Build Coastguard Worker void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) {
1154*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
1155*6777b538SAndroid Build Coastguard Worker enabled_state_observers_.erase(
1156*6777b538SAndroid Build Coastguard Worker ranges::remove(enabled_state_observers_, listener),
1157*6777b538SAndroid Build Coastguard Worker enabled_state_observers_.end());
1158*6777b538SAndroid Build Coastguard Worker }
1159*6777b538SAndroid Build Coastguard Worker
AddOwnedEnabledStateObserver(std::unique_ptr<EnabledStateObserver> listener)1160*6777b538SAndroid Build Coastguard Worker void TraceLog::AddOwnedEnabledStateObserver(
1161*6777b538SAndroid Build Coastguard Worker std::unique_ptr<EnabledStateObserver> listener) {
1162*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
1163*6777b538SAndroid Build Coastguard Worker enabled_state_observers_.push_back(listener.get());
1164*6777b538SAndroid Build Coastguard Worker owned_enabled_state_observer_copy_.push_back(std::move(listener));
1165*6777b538SAndroid Build Coastguard Worker }
1166*6777b538SAndroid Build Coastguard Worker
HasEnabledStateObserver(EnabledStateObserver * listener) const1167*6777b538SAndroid Build Coastguard Worker bool TraceLog::HasEnabledStateObserver(EnabledStateObserver* listener) const {
1168*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
1169*6777b538SAndroid Build Coastguard Worker return Contains(enabled_state_observers_, listener);
1170*6777b538SAndroid Build Coastguard Worker }
1171*6777b538SAndroid Build Coastguard Worker
AddAsyncEnabledStateObserver(WeakPtr<AsyncEnabledStateObserver> listener)1172*6777b538SAndroid Build Coastguard Worker void TraceLog::AddAsyncEnabledStateObserver(
1173*6777b538SAndroid Build Coastguard Worker WeakPtr<AsyncEnabledStateObserver> listener) {
1174*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
1175*6777b538SAndroid Build Coastguard Worker async_observers_.emplace(listener.get(), RegisteredAsyncObserver(listener));
1176*6777b538SAndroid Build Coastguard Worker }
1177*6777b538SAndroid Build Coastguard Worker
RemoveAsyncEnabledStateObserver(AsyncEnabledStateObserver * listener)1178*6777b538SAndroid Build Coastguard Worker void TraceLog::RemoveAsyncEnabledStateObserver(
1179*6777b538SAndroid Build Coastguard Worker AsyncEnabledStateObserver* listener) {
1180*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
1181*6777b538SAndroid Build Coastguard Worker async_observers_.erase(listener);
1182*6777b538SAndroid Build Coastguard Worker }
1183*6777b538SAndroid Build Coastguard Worker
HasAsyncEnabledStateObserver(AsyncEnabledStateObserver * listener) const1184*6777b538SAndroid Build Coastguard Worker bool TraceLog::HasAsyncEnabledStateObserver(
1185*6777b538SAndroid Build Coastguard Worker AsyncEnabledStateObserver* listener) const {
1186*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
1187*6777b538SAndroid Build Coastguard Worker return Contains(async_observers_, listener);
1188*6777b538SAndroid Build Coastguard Worker }
1189*6777b538SAndroid Build Coastguard Worker
AddIncrementalStateObserver(IncrementalStateObserver * listener)1190*6777b538SAndroid Build Coastguard Worker void TraceLog::AddIncrementalStateObserver(IncrementalStateObserver* listener) {
1191*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
1192*6777b538SAndroid Build Coastguard Worker incremental_state_observers_.push_back(listener);
1193*6777b538SAndroid Build Coastguard Worker }
1194*6777b538SAndroid Build Coastguard Worker
RemoveIncrementalStateObserver(IncrementalStateObserver * listener)1195*6777b538SAndroid Build Coastguard Worker void TraceLog::RemoveIncrementalStateObserver(
1196*6777b538SAndroid Build Coastguard Worker IncrementalStateObserver* listener) {
1197*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
1198*6777b538SAndroid Build Coastguard Worker incremental_state_observers_.erase(
1199*6777b538SAndroid Build Coastguard Worker ranges::remove(incremental_state_observers_, listener),
1200*6777b538SAndroid Build Coastguard Worker incremental_state_observers_.end());
1201*6777b538SAndroid Build Coastguard Worker }
1202*6777b538SAndroid Build Coastguard Worker
OnIncrementalStateCleared()1203*6777b538SAndroid Build Coastguard Worker void TraceLog::OnIncrementalStateCleared() {
1204*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
1205*6777b538SAndroid Build Coastguard Worker for (IncrementalStateObserver* observer : incremental_state_observers_)
1206*6777b538SAndroid Build Coastguard Worker observer->OnIncrementalStateCleared();
1207*6777b538SAndroid Build Coastguard Worker }
1208*6777b538SAndroid Build Coastguard Worker
GetStatus() const1209*6777b538SAndroid Build Coastguard Worker TraceLogStatus TraceLog::GetStatus() const {
1210*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1211*6777b538SAndroid Build Coastguard Worker TraceLogStatus result;
1212*6777b538SAndroid Build Coastguard Worker result.event_capacity = static_cast<uint32_t>(logged_events_->Capacity());
1213*6777b538SAndroid Build Coastguard Worker result.event_count = static_cast<uint32_t>(logged_events_->Size());
1214*6777b538SAndroid Build Coastguard Worker return result;
1215*6777b538SAndroid Build Coastguard Worker }
1216*6777b538SAndroid Build Coastguard Worker
1217*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
BufferIsFull() const1218*6777b538SAndroid Build Coastguard Worker bool TraceLog::BufferIsFull() const {
1219*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1220*6777b538SAndroid Build Coastguard Worker return logged_events_->IsFull();
1221*6777b538SAndroid Build Coastguard Worker }
1222*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
1223*6777b538SAndroid Build Coastguard Worker
AddEventToThreadSharedChunkWhileLocked(TraceEventHandle * handle,bool check_buffer_is_full)1224*6777b538SAndroid Build Coastguard Worker TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked(
1225*6777b538SAndroid Build Coastguard Worker TraceEventHandle* handle,
1226*6777b538SAndroid Build Coastguard Worker bool check_buffer_is_full) {
1227*6777b538SAndroid Build Coastguard Worker if (thread_shared_chunk_ && thread_shared_chunk_->IsFull()) {
1228*6777b538SAndroid Build Coastguard Worker logged_events_->ReturnChunk(thread_shared_chunk_index_,
1229*6777b538SAndroid Build Coastguard Worker std::move(thread_shared_chunk_));
1230*6777b538SAndroid Build Coastguard Worker }
1231*6777b538SAndroid Build Coastguard Worker
1232*6777b538SAndroid Build Coastguard Worker if (!thread_shared_chunk_) {
1233*6777b538SAndroid Build Coastguard Worker thread_shared_chunk_ =
1234*6777b538SAndroid Build Coastguard Worker logged_events_->GetChunk(&thread_shared_chunk_index_);
1235*6777b538SAndroid Build Coastguard Worker if (check_buffer_is_full)
1236*6777b538SAndroid Build Coastguard Worker CheckIfBufferIsFullWhileLocked();
1237*6777b538SAndroid Build Coastguard Worker }
1238*6777b538SAndroid Build Coastguard Worker if (!thread_shared_chunk_)
1239*6777b538SAndroid Build Coastguard Worker return nullptr;
1240*6777b538SAndroid Build Coastguard Worker
1241*6777b538SAndroid Build Coastguard Worker size_t event_index;
1242*6777b538SAndroid Build Coastguard Worker TraceEvent* trace_event = thread_shared_chunk_->AddTraceEvent(&event_index);
1243*6777b538SAndroid Build Coastguard Worker if (trace_event && handle) {
1244*6777b538SAndroid Build Coastguard Worker MakeHandle(thread_shared_chunk_->seq(), thread_shared_chunk_index_,
1245*6777b538SAndroid Build Coastguard Worker event_index, handle);
1246*6777b538SAndroid Build Coastguard Worker }
1247*6777b538SAndroid Build Coastguard Worker return trace_event;
1248*6777b538SAndroid Build Coastguard Worker }
1249*6777b538SAndroid Build Coastguard Worker
CheckIfBufferIsFullWhileLocked()1250*6777b538SAndroid Build Coastguard Worker void TraceLog::CheckIfBufferIsFullWhileLocked() {
1251*6777b538SAndroid Build Coastguard Worker if (logged_events_->IsFull()) {
1252*6777b538SAndroid Build Coastguard Worker if (buffer_limit_reached_timestamp_.is_null()) {
1253*6777b538SAndroid Build Coastguard Worker buffer_limit_reached_timestamp_ = OffsetNow();
1254*6777b538SAndroid Build Coastguard Worker }
1255*6777b538SAndroid Build Coastguard Worker SetDisabledWhileLocked(RECORDING_MODE);
1256*6777b538SAndroid Build Coastguard Worker }
1257*6777b538SAndroid Build Coastguard Worker }
1258*6777b538SAndroid Build Coastguard Worker
1259*6777b538SAndroid Build Coastguard Worker // Flush() works as the following:
1260*6777b538SAndroid Build Coastguard Worker // 1. Flush() is called in thread A whose task runner is saved in
1261*6777b538SAndroid Build Coastguard Worker // flush_task_runner_;
1262*6777b538SAndroid Build Coastguard Worker // 2. If thread_message_loops_ is not empty, thread A posts task to each message
1263*6777b538SAndroid Build Coastguard Worker // loop to flush the thread local buffers; otherwise finish the flush;
1264*6777b538SAndroid Build Coastguard Worker // 3. FlushCurrentThread() deletes the thread local event buffer:
1265*6777b538SAndroid Build Coastguard Worker // - The last batch of events of the thread are flushed into the main buffer;
1266*6777b538SAndroid Build Coastguard Worker // - The message loop will be removed from thread_message_loops_;
1267*6777b538SAndroid Build Coastguard Worker // If this is the last message loop, finish the flush;
1268*6777b538SAndroid Build Coastguard Worker // 4. If any thread hasn't finish its flush in time, finish the flush.
Flush(const TraceLog::OutputCallback & cb,bool use_worker_thread)1269*6777b538SAndroid Build Coastguard Worker void TraceLog::Flush(const TraceLog::OutputCallback& cb,
1270*6777b538SAndroid Build Coastguard Worker bool use_worker_thread) {
1271*6777b538SAndroid Build Coastguard Worker FlushInternal(cb, use_worker_thread, false);
1272*6777b538SAndroid Build Coastguard Worker }
1273*6777b538SAndroid Build Coastguard Worker
CancelTracing(const OutputCallback & cb)1274*6777b538SAndroid Build Coastguard Worker void TraceLog::CancelTracing(const OutputCallback& cb) {
1275*6777b538SAndroid Build Coastguard Worker SetDisabled();
1276*6777b538SAndroid Build Coastguard Worker FlushInternal(cb, false, true);
1277*6777b538SAndroid Build Coastguard Worker }
1278*6777b538SAndroid Build Coastguard Worker
FlushInternal(const TraceLog::OutputCallback & cb,bool use_worker_thread,bool discard_events)1279*6777b538SAndroid Build Coastguard Worker void TraceLog::FlushInternal(const TraceLog::OutputCallback& cb,
1280*6777b538SAndroid Build Coastguard Worker bool use_worker_thread,
1281*6777b538SAndroid Build Coastguard Worker bool discard_events) {
1282*6777b538SAndroid Build Coastguard Worker use_worker_thread_ = use_worker_thread;
1283*6777b538SAndroid Build Coastguard Worker
1284*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_TRACE_PROCESSOR)
1285*6777b538SAndroid Build Coastguard Worker TrackEvent::Flush();
1286*6777b538SAndroid Build Coastguard Worker
1287*6777b538SAndroid Build Coastguard Worker if (!tracing_session_ || discard_events) {
1288*6777b538SAndroid Build Coastguard Worker tracing_session_.reset();
1289*6777b538SAndroid Build Coastguard Worker scoped_refptr<RefCountedString> empty_result = new RefCountedString;
1290*6777b538SAndroid Build Coastguard Worker cb.Run(empty_result, /*has_more_events=*/false);
1291*6777b538SAndroid Build Coastguard Worker return;
1292*6777b538SAndroid Build Coastguard Worker }
1293*6777b538SAndroid Build Coastguard Worker
1294*6777b538SAndroid Build Coastguard Worker bool convert_to_json = true;
1295*6777b538SAndroid Build Coastguard Worker for (const auto& data_source : perfetto_config_.data_sources()) {
1296*6777b538SAndroid Build Coastguard Worker if (data_source.config().has_chrome_config() &&
1297*6777b538SAndroid Build Coastguard Worker data_source.config().chrome_config().has_convert_to_legacy_json()) {
1298*6777b538SAndroid Build Coastguard Worker convert_to_json =
1299*6777b538SAndroid Build Coastguard Worker data_source.config().chrome_config().convert_to_legacy_json();
1300*6777b538SAndroid Build Coastguard Worker break;
1301*6777b538SAndroid Build Coastguard Worker }
1302*6777b538SAndroid Build Coastguard Worker }
1303*6777b538SAndroid Build Coastguard Worker
1304*6777b538SAndroid Build Coastguard Worker if (convert_to_json) {
1305*6777b538SAndroid Build Coastguard Worker perfetto::trace_processor::Config processor_config;
1306*6777b538SAndroid Build Coastguard Worker trace_processor_ =
1307*6777b538SAndroid Build Coastguard Worker perfetto::trace_processor::TraceProcessorStorage::CreateInstance(
1308*6777b538SAndroid Build Coastguard Worker processor_config);
1309*6777b538SAndroid Build Coastguard Worker json_output_writer_.reset(new JsonStringOutputWriter(
1310*6777b538SAndroid Build Coastguard Worker use_worker_thread ? SingleThreadTaskRunner::GetCurrentDefault()
1311*6777b538SAndroid Build Coastguard Worker : nullptr,
1312*6777b538SAndroid Build Coastguard Worker cb));
1313*6777b538SAndroid Build Coastguard Worker } else {
1314*6777b538SAndroid Build Coastguard Worker proto_output_callback_ = std::move(cb);
1315*6777b538SAndroid Build Coastguard Worker }
1316*6777b538SAndroid Build Coastguard Worker
1317*6777b538SAndroid Build Coastguard Worker if (use_worker_thread) {
1318*6777b538SAndroid Build Coastguard Worker tracing_session_->ReadTrace(
1319*6777b538SAndroid Build Coastguard Worker [this](perfetto::TracingSession::ReadTraceCallbackArgs args) {
1320*6777b538SAndroid Build Coastguard Worker OnTraceData(args.data, args.size, args.has_more);
1321*6777b538SAndroid Build Coastguard Worker });
1322*6777b538SAndroid Build Coastguard Worker } else {
1323*6777b538SAndroid Build Coastguard Worker auto data = tracing_session_->ReadTraceBlocking();
1324*6777b538SAndroid Build Coastguard Worker OnTraceData(data.data(), data.size(), /*has_more=*/false);
1325*6777b538SAndroid Build Coastguard Worker }
1326*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
1327*6777b538SAndroid Build Coastguard Worker // Trace processor isn't enabled so we can't convert the resulting trace into
1328*6777b538SAndroid Build Coastguard Worker // JSON.
1329*6777b538SAndroid Build Coastguard Worker CHECK(false) << "JSON tracing isn't supported";
1330*6777b538SAndroid Build Coastguard Worker #else
1331*6777b538SAndroid Build Coastguard Worker if (IsEnabled()) {
1332*6777b538SAndroid Build Coastguard Worker // Can't flush when tracing is enabled because otherwise PostTask would
1333*6777b538SAndroid Build Coastguard Worker // - generate more trace events;
1334*6777b538SAndroid Build Coastguard Worker // - deschedule the calling thread on some platforms causing inaccurate
1335*6777b538SAndroid Build Coastguard Worker // timing of the trace events.
1336*6777b538SAndroid Build Coastguard Worker scoped_refptr<RefCountedString> empty_result = new RefCountedString;
1337*6777b538SAndroid Build Coastguard Worker if (!cb.is_null())
1338*6777b538SAndroid Build Coastguard Worker cb.Run(empty_result, false);
1339*6777b538SAndroid Build Coastguard Worker LOG(WARNING) << "Ignored TraceLog::Flush called when tracing is enabled";
1340*6777b538SAndroid Build Coastguard Worker return;
1341*6777b538SAndroid Build Coastguard Worker }
1342*6777b538SAndroid Build Coastguard Worker
1343*6777b538SAndroid Build Coastguard Worker int gen = generation();
1344*6777b538SAndroid Build Coastguard Worker // Copy of thread_task_runners_ to be used without locking.
1345*6777b538SAndroid Build Coastguard Worker std::vector<scoped_refptr<SingleThreadTaskRunner>> task_runners;
1346*6777b538SAndroid Build Coastguard Worker {
1347*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1348*6777b538SAndroid Build Coastguard Worker DCHECK(!flush_task_runner_);
1349*6777b538SAndroid Build Coastguard Worker flush_task_runner_ = SequencedTaskRunner::HasCurrentDefault()
1350*6777b538SAndroid Build Coastguard Worker ? SequencedTaskRunner::GetCurrentDefault()
1351*6777b538SAndroid Build Coastguard Worker : nullptr;
1352*6777b538SAndroid Build Coastguard Worker DCHECK(thread_task_runners_.empty() || flush_task_runner_);
1353*6777b538SAndroid Build Coastguard Worker flush_output_callback_ = cb;
1354*6777b538SAndroid Build Coastguard Worker
1355*6777b538SAndroid Build Coastguard Worker if (thread_shared_chunk_) {
1356*6777b538SAndroid Build Coastguard Worker logged_events_->ReturnChunk(thread_shared_chunk_index_,
1357*6777b538SAndroid Build Coastguard Worker std::move(thread_shared_chunk_));
1358*6777b538SAndroid Build Coastguard Worker }
1359*6777b538SAndroid Build Coastguard Worker
1360*6777b538SAndroid Build Coastguard Worker for (const auto& it : thread_task_runners_)
1361*6777b538SAndroid Build Coastguard Worker task_runners.push_back(it.second);
1362*6777b538SAndroid Build Coastguard Worker }
1363*6777b538SAndroid Build Coastguard Worker
1364*6777b538SAndroid Build Coastguard Worker if (!task_runners.empty()) {
1365*6777b538SAndroid Build Coastguard Worker for (auto& task_runner : task_runners) {
1366*6777b538SAndroid Build Coastguard Worker task_runner->PostTask(
1367*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&TraceLog::FlushCurrentThread, Unretained(this),
1368*6777b538SAndroid Build Coastguard Worker gen, discard_events));
1369*6777b538SAndroid Build Coastguard Worker }
1370*6777b538SAndroid Build Coastguard Worker flush_task_runner_->PostDelayedTask(
1371*6777b538SAndroid Build Coastguard Worker FROM_HERE,
1372*6777b538SAndroid Build Coastguard Worker BindOnce(&TraceLog::OnFlushTimeout, Unretained(this), gen,
1373*6777b538SAndroid Build Coastguard Worker discard_events),
1374*6777b538SAndroid Build Coastguard Worker kThreadFlushTimeout);
1375*6777b538SAndroid Build Coastguard Worker return;
1376*6777b538SAndroid Build Coastguard Worker }
1377*6777b538SAndroid Build Coastguard Worker
1378*6777b538SAndroid Build Coastguard Worker FinishFlush(gen, discard_events);
1379*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(USE_PERFETTO_TRACE_PROCESSOR)
1380*6777b538SAndroid Build Coastguard Worker }
1381*6777b538SAndroid Build Coastguard Worker
1382*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_TRACE_PROCESSOR)
OnTraceData(const char * data,size_t size,bool has_more)1383*6777b538SAndroid Build Coastguard Worker void TraceLog::OnTraceData(const char* data, size_t size, bool has_more) {
1384*6777b538SAndroid Build Coastguard Worker if (proto_output_callback_) {
1385*6777b538SAndroid Build Coastguard Worker scoped_refptr<RefCountedString> chunk = new RefCountedString();
1386*6777b538SAndroid Build Coastguard Worker if (size)
1387*6777b538SAndroid Build Coastguard Worker chunk->data().assign(data, size);
1388*6777b538SAndroid Build Coastguard Worker proto_output_callback_.Run(std::move(chunk), has_more);
1389*6777b538SAndroid Build Coastguard Worker if (!has_more) {
1390*6777b538SAndroid Build Coastguard Worker proto_output_callback_.Reset();
1391*6777b538SAndroid Build Coastguard Worker tracing_session_.reset();
1392*6777b538SAndroid Build Coastguard Worker }
1393*6777b538SAndroid Build Coastguard Worker return;
1394*6777b538SAndroid Build Coastguard Worker }
1395*6777b538SAndroid Build Coastguard Worker if (size) {
1396*6777b538SAndroid Build Coastguard Worker std::unique_ptr<uint8_t[]> data_copy(new uint8_t[size]);
1397*6777b538SAndroid Build Coastguard Worker memcpy(&data_copy[0], data, size);
1398*6777b538SAndroid Build Coastguard Worker auto status = trace_processor_->Parse(std::move(data_copy), size);
1399*6777b538SAndroid Build Coastguard Worker DCHECK(status.ok()) << status.message();
1400*6777b538SAndroid Build Coastguard Worker }
1401*6777b538SAndroid Build Coastguard Worker if (has_more)
1402*6777b538SAndroid Build Coastguard Worker return;
1403*6777b538SAndroid Build Coastguard Worker trace_processor_->NotifyEndOfFile();
1404*6777b538SAndroid Build Coastguard Worker
1405*6777b538SAndroid Build Coastguard Worker auto status = perfetto::trace_processor::json::ExportJson(
1406*6777b538SAndroid Build Coastguard Worker trace_processor_.get(), json_output_writer_.get());
1407*6777b538SAndroid Build Coastguard Worker DCHECK(status.ok()) << status.message();
1408*6777b538SAndroid Build Coastguard Worker trace_processor_.reset();
1409*6777b538SAndroid Build Coastguard Worker tracing_session_.reset();
1410*6777b538SAndroid Build Coastguard Worker json_output_writer_.reset();
1411*6777b538SAndroid Build Coastguard Worker }
1412*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(USE_PERFETTO_TRACE_PROCESSOR)
1413*6777b538SAndroid Build Coastguard Worker
1414*6777b538SAndroid Build Coastguard Worker // Usually it runs on a different thread.
ConvertTraceEventsToTraceFormat(std::unique_ptr<TraceBuffer> logged_events,const OutputCallback & flush_output_callback,const ArgumentFilterPredicate & argument_filter_predicate)1415*6777b538SAndroid Build Coastguard Worker void TraceLog::ConvertTraceEventsToTraceFormat(
1416*6777b538SAndroid Build Coastguard Worker std::unique_ptr<TraceBuffer> logged_events,
1417*6777b538SAndroid Build Coastguard Worker const OutputCallback& flush_output_callback,
1418*6777b538SAndroid Build Coastguard Worker const ArgumentFilterPredicate& argument_filter_predicate) {
1419*6777b538SAndroid Build Coastguard Worker if (flush_output_callback.is_null())
1420*6777b538SAndroid Build Coastguard Worker return;
1421*6777b538SAndroid Build Coastguard Worker
1422*6777b538SAndroid Build Coastguard Worker HEAP_PROFILER_SCOPED_IGNORE;
1423*6777b538SAndroid Build Coastguard Worker // The callback need to be called at least once even if there is no events
1424*6777b538SAndroid Build Coastguard Worker // to let the caller know the completion of flush.
1425*6777b538SAndroid Build Coastguard Worker scoped_refptr<RefCountedString> json_events_str_ptr = new RefCountedString();
1426*6777b538SAndroid Build Coastguard Worker const size_t kReserveCapacity = kTraceEventBufferSizeInBytes * 5 / 4;
1427*6777b538SAndroid Build Coastguard Worker json_events_str_ptr->data().reserve(kReserveCapacity);
1428*6777b538SAndroid Build Coastguard Worker while (const TraceBufferChunk* chunk = logged_events->NextChunk()) {
1429*6777b538SAndroid Build Coastguard Worker for (size_t j = 0; j < chunk->size(); ++j) {
1430*6777b538SAndroid Build Coastguard Worker size_t size = json_events_str_ptr->size();
1431*6777b538SAndroid Build Coastguard Worker if (size > kTraceEventBufferSizeInBytes) {
1432*6777b538SAndroid Build Coastguard Worker flush_output_callback.Run(json_events_str_ptr, true);
1433*6777b538SAndroid Build Coastguard Worker json_events_str_ptr = new RefCountedString();
1434*6777b538SAndroid Build Coastguard Worker json_events_str_ptr->data().reserve(kReserveCapacity);
1435*6777b538SAndroid Build Coastguard Worker } else if (size) {
1436*6777b538SAndroid Build Coastguard Worker json_events_str_ptr->data().append(",\n");
1437*6777b538SAndroid Build Coastguard Worker }
1438*6777b538SAndroid Build Coastguard Worker chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data()),
1439*6777b538SAndroid Build Coastguard Worker argument_filter_predicate);
1440*6777b538SAndroid Build Coastguard Worker }
1441*6777b538SAndroid Build Coastguard Worker }
1442*6777b538SAndroid Build Coastguard Worker flush_output_callback.Run(json_events_str_ptr, false);
1443*6777b538SAndroid Build Coastguard Worker }
1444*6777b538SAndroid Build Coastguard Worker
FinishFlush(int generation,bool discard_events)1445*6777b538SAndroid Build Coastguard Worker void TraceLog::FinishFlush(int generation, bool discard_events) {
1446*6777b538SAndroid Build Coastguard Worker std::unique_ptr<TraceBuffer> previous_logged_events;
1447*6777b538SAndroid Build Coastguard Worker OutputCallback flush_output_callback;
1448*6777b538SAndroid Build Coastguard Worker ArgumentFilterPredicate argument_filter_predicate;
1449*6777b538SAndroid Build Coastguard Worker
1450*6777b538SAndroid Build Coastguard Worker if (!CheckGeneration(generation))
1451*6777b538SAndroid Build Coastguard Worker return;
1452*6777b538SAndroid Build Coastguard Worker
1453*6777b538SAndroid Build Coastguard Worker {
1454*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1455*6777b538SAndroid Build Coastguard Worker
1456*6777b538SAndroid Build Coastguard Worker previous_logged_events.swap(logged_events_);
1457*6777b538SAndroid Build Coastguard Worker UseNextTraceBuffer();
1458*6777b538SAndroid Build Coastguard Worker thread_task_runners_.clear();
1459*6777b538SAndroid Build Coastguard Worker
1460*6777b538SAndroid Build Coastguard Worker flush_task_runner_ = nullptr;
1461*6777b538SAndroid Build Coastguard Worker flush_output_callback = flush_output_callback_;
1462*6777b538SAndroid Build Coastguard Worker flush_output_callback_.Reset();
1463*6777b538SAndroid Build Coastguard Worker
1464*6777b538SAndroid Build Coastguard Worker if (trace_options() & kInternalEnableArgumentFilter) {
1465*6777b538SAndroid Build Coastguard Worker // If argument filtering is activated and there is no filtering predicate,
1466*6777b538SAndroid Build Coastguard Worker // use the safe default filtering predicate.
1467*6777b538SAndroid Build Coastguard Worker if (argument_filter_predicate_.is_null()) {
1468*6777b538SAndroid Build Coastguard Worker argument_filter_predicate =
1469*6777b538SAndroid Build Coastguard Worker base::BindRepeating(&DefaultIsTraceEventArgsAllowlisted);
1470*6777b538SAndroid Build Coastguard Worker } else {
1471*6777b538SAndroid Build Coastguard Worker argument_filter_predicate = argument_filter_predicate_;
1472*6777b538SAndroid Build Coastguard Worker }
1473*6777b538SAndroid Build Coastguard Worker }
1474*6777b538SAndroid Build Coastguard Worker }
1475*6777b538SAndroid Build Coastguard Worker
1476*6777b538SAndroid Build Coastguard Worker if (discard_events) {
1477*6777b538SAndroid Build Coastguard Worker if (!flush_output_callback.is_null()) {
1478*6777b538SAndroid Build Coastguard Worker scoped_refptr<RefCountedString> empty_result = new RefCountedString;
1479*6777b538SAndroid Build Coastguard Worker flush_output_callback.Run(empty_result, false);
1480*6777b538SAndroid Build Coastguard Worker }
1481*6777b538SAndroid Build Coastguard Worker return;
1482*6777b538SAndroid Build Coastguard Worker }
1483*6777b538SAndroid Build Coastguard Worker
1484*6777b538SAndroid Build Coastguard Worker if (use_worker_thread_) {
1485*6777b538SAndroid Build Coastguard Worker base::ThreadPool::PostTask(
1486*6777b538SAndroid Build Coastguard Worker FROM_HERE,
1487*6777b538SAndroid Build Coastguard Worker {MayBlock(), TaskPriority::BEST_EFFORT,
1488*6777b538SAndroid Build Coastguard Worker TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
1489*6777b538SAndroid Build Coastguard Worker BindOnce(&TraceLog::ConvertTraceEventsToTraceFormat,
1490*6777b538SAndroid Build Coastguard Worker std::move(previous_logged_events), flush_output_callback,
1491*6777b538SAndroid Build Coastguard Worker argument_filter_predicate));
1492*6777b538SAndroid Build Coastguard Worker return;
1493*6777b538SAndroid Build Coastguard Worker }
1494*6777b538SAndroid Build Coastguard Worker
1495*6777b538SAndroid Build Coastguard Worker ConvertTraceEventsToTraceFormat(std::move(previous_logged_events),
1496*6777b538SAndroid Build Coastguard Worker flush_output_callback,
1497*6777b538SAndroid Build Coastguard Worker argument_filter_predicate);
1498*6777b538SAndroid Build Coastguard Worker }
1499*6777b538SAndroid Build Coastguard Worker
1500*6777b538SAndroid Build Coastguard Worker // Run in each thread holding a local event buffer.
FlushCurrentThread(int generation,bool discard_events)1501*6777b538SAndroid Build Coastguard Worker void TraceLog::FlushCurrentThread(int generation, bool discard_events) {
1502*6777b538SAndroid Build Coastguard Worker {
1503*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1504*6777b538SAndroid Build Coastguard Worker if (!CheckGeneration(generation) || !flush_task_runner_) {
1505*6777b538SAndroid Build Coastguard Worker // This is late. The corresponding flush has finished.
1506*6777b538SAndroid Build Coastguard Worker return;
1507*6777b538SAndroid Build Coastguard Worker }
1508*6777b538SAndroid Build Coastguard Worker }
1509*6777b538SAndroid Build Coastguard Worker
1510*6777b538SAndroid Build Coastguard Worker // This will flush the thread local buffer.
1511*6777b538SAndroid Build Coastguard Worker delete thread_local_event_buffer;
1512*6777b538SAndroid Build Coastguard Worker
1513*6777b538SAndroid Build Coastguard Worker auto on_flush_override = on_flush_override_.load(std::memory_order_relaxed);
1514*6777b538SAndroid Build Coastguard Worker if (on_flush_override) {
1515*6777b538SAndroid Build Coastguard Worker on_flush_override();
1516*6777b538SAndroid Build Coastguard Worker }
1517*6777b538SAndroid Build Coastguard Worker
1518*6777b538SAndroid Build Coastguard Worker // Scheduler uses TRACE_EVENT macros when posting a task, which can lead
1519*6777b538SAndroid Build Coastguard Worker // to acquiring a tracing lock. Given that posting a task requires grabbing
1520*6777b538SAndroid Build Coastguard Worker // a scheduler lock, we need to post this task outside tracing lock to avoid
1521*6777b538SAndroid Build Coastguard Worker // deadlocks.
1522*6777b538SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> cached_flush_task_runner;
1523*6777b538SAndroid Build Coastguard Worker {
1524*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1525*6777b538SAndroid Build Coastguard Worker cached_flush_task_runner = flush_task_runner_;
1526*6777b538SAndroid Build Coastguard Worker if (!CheckGeneration(generation) || !flush_task_runner_ ||
1527*6777b538SAndroid Build Coastguard Worker !thread_task_runners_.empty())
1528*6777b538SAndroid Build Coastguard Worker return;
1529*6777b538SAndroid Build Coastguard Worker }
1530*6777b538SAndroid Build Coastguard Worker cached_flush_task_runner->PostTask(
1531*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&TraceLog::FinishFlush, Unretained(this), generation,
1532*6777b538SAndroid Build Coastguard Worker discard_events));
1533*6777b538SAndroid Build Coastguard Worker }
1534*6777b538SAndroid Build Coastguard Worker
OnFlushTimeout(int generation,bool discard_events)1535*6777b538SAndroid Build Coastguard Worker void TraceLog::OnFlushTimeout(int generation, bool discard_events) {
1536*6777b538SAndroid Build Coastguard Worker {
1537*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1538*6777b538SAndroid Build Coastguard Worker if (!CheckGeneration(generation) || !flush_task_runner_) {
1539*6777b538SAndroid Build Coastguard Worker // Flush has finished before timeout.
1540*6777b538SAndroid Build Coastguard Worker return;
1541*6777b538SAndroid Build Coastguard Worker }
1542*6777b538SAndroid Build Coastguard Worker
1543*6777b538SAndroid Build Coastguard Worker LOG(WARNING)
1544*6777b538SAndroid Build Coastguard Worker << "The following threads haven't finished flush in time. "
1545*6777b538SAndroid Build Coastguard Worker "If this happens stably for some thread, please call "
1546*6777b538SAndroid Build Coastguard Worker "TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop() from "
1547*6777b538SAndroid Build Coastguard Worker "the thread to avoid its trace events from being lost.";
1548*6777b538SAndroid Build Coastguard Worker for (const auto& it : thread_task_runners_) {
1549*6777b538SAndroid Build Coastguard Worker LOG(WARNING) << "Thread: "
1550*6777b538SAndroid Build Coastguard Worker << ThreadIdNameManager::GetInstance()->GetName(it.first);
1551*6777b538SAndroid Build Coastguard Worker }
1552*6777b538SAndroid Build Coastguard Worker }
1553*6777b538SAndroid Build Coastguard Worker FinishFlush(generation, discard_events);
1554*6777b538SAndroid Build Coastguard Worker }
1555*6777b538SAndroid Build Coastguard Worker
UseNextTraceBuffer()1556*6777b538SAndroid Build Coastguard Worker void TraceLog::UseNextTraceBuffer() {
1557*6777b538SAndroid Build Coastguard Worker logged_events_.reset(CreateTraceBuffer());
1558*6777b538SAndroid Build Coastguard Worker generation_.fetch_add(1, std::memory_order_relaxed);
1559*6777b538SAndroid Build Coastguard Worker thread_shared_chunk_.reset();
1560*6777b538SAndroid Build Coastguard Worker thread_shared_chunk_index_ = 0;
1561*6777b538SAndroid Build Coastguard Worker }
1562*6777b538SAndroid Build Coastguard Worker
ShouldAddAfterUpdatingState(char phase,const unsigned char * category_group_enabled,const char * name,uint64_t id,PlatformThreadId thread_id,const TimeTicks timestamp,TraceArguments * args)1563*6777b538SAndroid Build Coastguard Worker bool TraceLog::ShouldAddAfterUpdatingState(
1564*6777b538SAndroid Build Coastguard Worker char phase,
1565*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1566*6777b538SAndroid Build Coastguard Worker const char* name,
1567*6777b538SAndroid Build Coastguard Worker uint64_t id,
1568*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id,
1569*6777b538SAndroid Build Coastguard Worker const TimeTicks timestamp,
1570*6777b538SAndroid Build Coastguard Worker TraceArguments* args) {
1571*6777b538SAndroid Build Coastguard Worker if (!*category_group_enabled)
1572*6777b538SAndroid Build Coastguard Worker return false;
1573*6777b538SAndroid Build Coastguard Worker
1574*6777b538SAndroid Build Coastguard Worker // Avoid re-entrance of AddTraceEvent. This may happen in GPU process when
1575*6777b538SAndroid Build Coastguard Worker // ECHO_TO_CONSOLE is enabled: AddTraceEvent -> LOG(ERROR) ->
1576*6777b538SAndroid Build Coastguard Worker // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ...
1577*6777b538SAndroid Build Coastguard Worker if (thread_is_in_trace_event) {
1578*6777b538SAndroid Build Coastguard Worker return false;
1579*6777b538SAndroid Build Coastguard Worker }
1580*6777b538SAndroid Build Coastguard Worker
1581*6777b538SAndroid Build Coastguard Worker // Check and update the current thread name only if the event is for the
1582*6777b538SAndroid Build Coastguard Worker // current thread to avoid locks in most cases.
1583*6777b538SAndroid Build Coastguard Worker if (thread_id == PlatformThread::CurrentId()) {
1584*6777b538SAndroid Build Coastguard Worker const char* new_name =
1585*6777b538SAndroid Build Coastguard Worker ThreadIdNameManager::GetInstance()->GetNameForCurrentThread();
1586*6777b538SAndroid Build Coastguard Worker // Check if the thread name has been set or changed since the previous
1587*6777b538SAndroid Build Coastguard Worker // call (if any), but don't bother if the new name is empty. Note this will
1588*6777b538SAndroid Build Coastguard Worker // not detect a thread name change within the same char* buffer address: we
1589*6777b538SAndroid Build Coastguard Worker // favor common case performance over corner case correctness.
1590*6777b538SAndroid Build Coastguard Worker thread_local const char* current_thread_name = nullptr;
1591*6777b538SAndroid Build Coastguard Worker if (new_name != current_thread_name && new_name && *new_name) {
1592*6777b538SAndroid Build Coastguard Worker current_thread_name = new_name;
1593*6777b538SAndroid Build Coastguard Worker
1594*6777b538SAndroid Build Coastguard Worker AutoLock thread_info_lock(thread_info_lock_);
1595*6777b538SAndroid Build Coastguard Worker
1596*6777b538SAndroid Build Coastguard Worker auto existing_name = thread_names_.find(thread_id);
1597*6777b538SAndroid Build Coastguard Worker if (existing_name == thread_names_.end()) {
1598*6777b538SAndroid Build Coastguard Worker // This is a new thread id, and a new name.
1599*6777b538SAndroid Build Coastguard Worker thread_names_[thread_id] = new_name;
1600*6777b538SAndroid Build Coastguard Worker } else {
1601*6777b538SAndroid Build Coastguard Worker // This is a thread id that we've seen before, but potentially with a
1602*6777b538SAndroid Build Coastguard Worker // new name.
1603*6777b538SAndroid Build Coastguard Worker std::vector<std::string_view> existing_names = base::SplitStringPiece(
1604*6777b538SAndroid Build Coastguard Worker existing_name->second, ",", base::KEEP_WHITESPACE,
1605*6777b538SAndroid Build Coastguard Worker base::SPLIT_WANT_NONEMPTY);
1606*6777b538SAndroid Build Coastguard Worker if (!Contains(existing_names, new_name)) {
1607*6777b538SAndroid Build Coastguard Worker if (!existing_names.empty()) {
1608*6777b538SAndroid Build Coastguard Worker existing_name->second.push_back(',');
1609*6777b538SAndroid Build Coastguard Worker }
1610*6777b538SAndroid Build Coastguard Worker existing_name->second.append(new_name);
1611*6777b538SAndroid Build Coastguard Worker }
1612*6777b538SAndroid Build Coastguard Worker }
1613*6777b538SAndroid Build Coastguard Worker }
1614*6777b538SAndroid Build Coastguard Worker }
1615*6777b538SAndroid Build Coastguard Worker
1616*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
1617*6777b538SAndroid Build Coastguard Worker // This is done sooner rather than later, to avoid creating the event and
1618*6777b538SAndroid Build Coastguard Worker // acquiring the lock, which is not needed for ETW as it's already threadsafe.
1619*6777b538SAndroid Build Coastguard Worker if (*category_group_enabled & TraceCategory::ENABLED_FOR_ETW_EXPORT) {
1620*6777b538SAndroid Build Coastguard Worker // ETW export expects non-null event names.
1621*6777b538SAndroid Build Coastguard Worker name = name ? name : "";
1622*6777b538SAndroid Build Coastguard Worker TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id,
1623*6777b538SAndroid Build Coastguard Worker timestamp, args);
1624*6777b538SAndroid Build Coastguard Worker }
1625*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
1626*6777b538SAndroid Build Coastguard Worker return true;
1627*6777b538SAndroid Build Coastguard Worker }
1628*6777b538SAndroid Build Coastguard Worker
AddTraceEvent(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,TraceArguments * args,unsigned int flags)1629*6777b538SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEvent(
1630*6777b538SAndroid Build Coastguard Worker char phase,
1631*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1632*6777b538SAndroid Build Coastguard Worker const char* name,
1633*6777b538SAndroid Build Coastguard Worker const char* scope,
1634*6777b538SAndroid Build Coastguard Worker uint64_t id,
1635*6777b538SAndroid Build Coastguard Worker TraceArguments* args,
1636*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
1637*6777b538SAndroid Build Coastguard Worker auto thread_id = base::PlatformThread::CurrentId();
1638*6777b538SAndroid Build Coastguard Worker base::TimeTicks now = TRACE_TIME_TICKS_NOW();
1639*6777b538SAndroid Build Coastguard Worker return AddTraceEventWithThreadIdAndTimestamp(
1640*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id,
1641*6777b538SAndroid Build Coastguard Worker trace_event_internal::kNoId, // bind_id
1642*6777b538SAndroid Build Coastguard Worker thread_id, now, args, flags);
1643*6777b538SAndroid Build Coastguard Worker }
1644*6777b538SAndroid Build Coastguard Worker
AddTraceEventWithBindId(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,uint64_t bind_id,TraceArguments * args,unsigned int flags)1645*6777b538SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEventWithBindId(
1646*6777b538SAndroid Build Coastguard Worker char phase,
1647*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1648*6777b538SAndroid Build Coastguard Worker const char* name,
1649*6777b538SAndroid Build Coastguard Worker const char* scope,
1650*6777b538SAndroid Build Coastguard Worker uint64_t id,
1651*6777b538SAndroid Build Coastguard Worker uint64_t bind_id,
1652*6777b538SAndroid Build Coastguard Worker TraceArguments* args,
1653*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
1654*6777b538SAndroid Build Coastguard Worker auto thread_id = base::PlatformThread::CurrentId();
1655*6777b538SAndroid Build Coastguard Worker base::TimeTicks now = TRACE_TIME_TICKS_NOW();
1656*6777b538SAndroid Build Coastguard Worker return AddTraceEventWithThreadIdAndTimestamp(
1657*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id, bind_id, thread_id, now,
1658*6777b538SAndroid Build Coastguard Worker args, flags | TRACE_EVENT_FLAG_HAS_CONTEXT_ID);
1659*6777b538SAndroid Build Coastguard Worker }
1660*6777b538SAndroid Build Coastguard Worker
AddTraceEventWithProcessId(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,ProcessId process_id,TraceArguments * args,unsigned int flags)1661*6777b538SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEventWithProcessId(
1662*6777b538SAndroid Build Coastguard Worker char phase,
1663*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1664*6777b538SAndroid Build Coastguard Worker const char* name,
1665*6777b538SAndroid Build Coastguard Worker const char* scope,
1666*6777b538SAndroid Build Coastguard Worker uint64_t id,
1667*6777b538SAndroid Build Coastguard Worker ProcessId process_id,
1668*6777b538SAndroid Build Coastguard Worker TraceArguments* args,
1669*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
1670*6777b538SAndroid Build Coastguard Worker base::TimeTicks now = TRACE_TIME_TICKS_NOW();
1671*6777b538SAndroid Build Coastguard Worker return AddTraceEventWithThreadIdAndTimestamp(
1672*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id,
1673*6777b538SAndroid Build Coastguard Worker trace_event_internal::kNoId, // bind_id
1674*6777b538SAndroid Build Coastguard Worker static_cast<PlatformThreadId>(process_id), now, args,
1675*6777b538SAndroid Build Coastguard Worker flags | TRACE_EVENT_FLAG_HAS_PROCESS_ID);
1676*6777b538SAndroid Build Coastguard Worker }
1677*6777b538SAndroid Build Coastguard Worker
1678*6777b538SAndroid Build Coastguard Worker // Handle legacy calls to AddTraceEventWithThreadIdAndTimestamp
1679*6777b538SAndroid Build Coastguard Worker // with kNoId as bind_id
AddTraceEventWithThreadIdAndTimestamp(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,PlatformThreadId thread_id,const TimeTicks & timestamp,TraceArguments * args,unsigned int flags)1680*6777b538SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
1681*6777b538SAndroid Build Coastguard Worker char phase,
1682*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1683*6777b538SAndroid Build Coastguard Worker const char* name,
1684*6777b538SAndroid Build Coastguard Worker const char* scope,
1685*6777b538SAndroid Build Coastguard Worker uint64_t id,
1686*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id,
1687*6777b538SAndroid Build Coastguard Worker const TimeTicks& timestamp,
1688*6777b538SAndroid Build Coastguard Worker TraceArguments* args,
1689*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
1690*6777b538SAndroid Build Coastguard Worker return AddTraceEventWithThreadIdAndTimestamp(
1691*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id,
1692*6777b538SAndroid Build Coastguard Worker trace_event_internal::kNoId, // bind_id
1693*6777b538SAndroid Build Coastguard Worker thread_id, timestamp, args, flags);
1694*6777b538SAndroid Build Coastguard Worker }
1695*6777b538SAndroid Build Coastguard Worker
AddTraceEventWithThreadIdAndTimestamp(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,uint64_t bind_id,PlatformThreadId thread_id,const TimeTicks & timestamp,TraceArguments * args,unsigned int flags)1696*6777b538SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
1697*6777b538SAndroid Build Coastguard Worker char phase,
1698*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1699*6777b538SAndroid Build Coastguard Worker const char* name,
1700*6777b538SAndroid Build Coastguard Worker const char* scope,
1701*6777b538SAndroid Build Coastguard Worker uint64_t id,
1702*6777b538SAndroid Build Coastguard Worker uint64_t bind_id,
1703*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id,
1704*6777b538SAndroid Build Coastguard Worker const TimeTicks& timestamp,
1705*6777b538SAndroid Build Coastguard Worker TraceArguments* args,
1706*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
1707*6777b538SAndroid Build Coastguard Worker ThreadTicks thread_now;
1708*6777b538SAndroid Build Coastguard Worker // If timestamp is provided explicitly, don't record thread time as it would
1709*6777b538SAndroid Build Coastguard Worker // be for the wrong timestamp. Similarly, if we record an event for another
1710*6777b538SAndroid Build Coastguard Worker // process or thread, we shouldn't report the current thread's thread time.
1711*6777b538SAndroid Build Coastguard Worker if (!(flags & TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP ||
1712*6777b538SAndroid Build Coastguard Worker flags & TRACE_EVENT_FLAG_HAS_PROCESS_ID ||
1713*6777b538SAndroid Build Coastguard Worker thread_id != PlatformThread::CurrentId())) {
1714*6777b538SAndroid Build Coastguard Worker thread_now = ThreadNow();
1715*6777b538SAndroid Build Coastguard Worker }
1716*6777b538SAndroid Build Coastguard Worker return AddTraceEventWithThreadIdAndTimestamps(
1717*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id, bind_id, thread_id,
1718*6777b538SAndroid Build Coastguard Worker timestamp, thread_now, args, flags);
1719*6777b538SAndroid Build Coastguard Worker }
1720*6777b538SAndroid Build Coastguard Worker
AddTraceEventWithThreadIdAndTimestamps(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,uint64_t bind_id,PlatformThreadId thread_id,const TimeTicks & timestamp,const ThreadTicks & thread_timestamp,TraceArguments * args,unsigned int flags)1721*6777b538SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamps(
1722*6777b538SAndroid Build Coastguard Worker char phase,
1723*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1724*6777b538SAndroid Build Coastguard Worker const char* name,
1725*6777b538SAndroid Build Coastguard Worker const char* scope,
1726*6777b538SAndroid Build Coastguard Worker uint64_t id,
1727*6777b538SAndroid Build Coastguard Worker uint64_t bind_id,
1728*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id,
1729*6777b538SAndroid Build Coastguard Worker const TimeTicks& timestamp,
1730*6777b538SAndroid Build Coastguard Worker const ThreadTicks& thread_timestamp,
1731*6777b538SAndroid Build Coastguard Worker TraceArguments* args,
1732*6777b538SAndroid Build Coastguard Worker unsigned int flags) NO_THREAD_SAFETY_ANALYSIS {
1733*6777b538SAndroid Build Coastguard Worker TraceEventHandle handle = {0, 0, 0};
1734*6777b538SAndroid Build Coastguard Worker if (!ShouldAddAfterUpdatingState(phase, category_group_enabled, name, id,
1735*6777b538SAndroid Build Coastguard Worker thread_id, timestamp, args)) {
1736*6777b538SAndroid Build Coastguard Worker return handle;
1737*6777b538SAndroid Build Coastguard Worker }
1738*6777b538SAndroid Build Coastguard Worker DCHECK(!timestamp.is_null());
1739*6777b538SAndroid Build Coastguard Worker
1740*6777b538SAndroid Build Coastguard Worker const AutoReset<bool> resetter(&thread_is_in_trace_event, true, false);
1741*6777b538SAndroid Build Coastguard Worker
1742*6777b538SAndroid Build Coastguard Worker // Flow bind_ids don't have scopes, so we need to mangle in-process ones to
1743*6777b538SAndroid Build Coastguard Worker // avoid collisions.
1744*6777b538SAndroid Build Coastguard Worker bool has_flow =
1745*6777b538SAndroid Build Coastguard Worker flags & (TRACE_EVENT_FLAG_FLOW_OUT | TRACE_EVENT_FLAG_FLOW_IN);
1746*6777b538SAndroid Build Coastguard Worker if (has_flow && (flags & TRACE_EVENT_FLAG_HAS_LOCAL_ID))
1747*6777b538SAndroid Build Coastguard Worker bind_id = MangleEventId(bind_id);
1748*6777b538SAndroid Build Coastguard Worker
1749*6777b538SAndroid Build Coastguard Worker TimeTicks offset_event_timestamp = OffsetTimestamp(timestamp);
1750*6777b538SAndroid Build Coastguard Worker
1751*6777b538SAndroid Build Coastguard Worker ThreadLocalEventBuffer* event_buffer = nullptr;
1752*6777b538SAndroid Build Coastguard Worker if (*category_group_enabled & RECORDING_MODE) {
1753*6777b538SAndroid Build Coastguard Worker // |thread_local_event_buffer| can be null if the current thread doesn't
1754*6777b538SAndroid Build Coastguard Worker // have a message loop or the message loop is blocked.
1755*6777b538SAndroid Build Coastguard Worker InitializeThreadLocalEventBufferIfSupported();
1756*6777b538SAndroid Build Coastguard Worker event_buffer = thread_local_event_buffer;
1757*6777b538SAndroid Build Coastguard Worker }
1758*6777b538SAndroid Build Coastguard Worker
1759*6777b538SAndroid Build Coastguard Worker if (*category_group_enabled & RECORDING_MODE) {
1760*6777b538SAndroid Build Coastguard Worker auto trace_event_override =
1761*6777b538SAndroid Build Coastguard Worker add_trace_event_override_.load(std::memory_order_relaxed);
1762*6777b538SAndroid Build Coastguard Worker if (trace_event_override) {
1763*6777b538SAndroid Build Coastguard Worker TraceEvent new_trace_event(
1764*6777b538SAndroid Build Coastguard Worker thread_id, offset_event_timestamp, thread_timestamp, phase,
1765*6777b538SAndroid Build Coastguard Worker category_group_enabled, name, scope, id, bind_id, args, flags);
1766*6777b538SAndroid Build Coastguard Worker
1767*6777b538SAndroid Build Coastguard Worker trace_event_override(&new_trace_event,
1768*6777b538SAndroid Build Coastguard Worker /*thread_will_flush=*/event_buffer != nullptr,
1769*6777b538SAndroid Build Coastguard Worker &handle);
1770*6777b538SAndroid Build Coastguard Worker return handle;
1771*6777b538SAndroid Build Coastguard Worker }
1772*6777b538SAndroid Build Coastguard Worker }
1773*6777b538SAndroid Build Coastguard Worker
1774*6777b538SAndroid Build Coastguard Worker std::string console_message;
1775*6777b538SAndroid Build Coastguard Worker
1776*6777b538SAndroid Build Coastguard Worker // If enabled for recording, the event should be added only if one of the
1777*6777b538SAndroid Build Coastguard Worker // filters indicates or category is not enabled for filtering.
1778*6777b538SAndroid Build Coastguard Worker if ((*category_group_enabled & TraceCategory::ENABLED_FOR_RECORDING)) {
1779*6777b538SAndroid Build Coastguard Worker OptionalAutoLock lock(&lock_);
1780*6777b538SAndroid Build Coastguard Worker
1781*6777b538SAndroid Build Coastguard Worker TraceEvent* trace_event = nullptr;
1782*6777b538SAndroid Build Coastguard Worker if (event_buffer) {
1783*6777b538SAndroid Build Coastguard Worker trace_event = event_buffer->AddTraceEvent(&handle);
1784*6777b538SAndroid Build Coastguard Worker } else {
1785*6777b538SAndroid Build Coastguard Worker lock.EnsureAcquired();
1786*6777b538SAndroid Build Coastguard Worker trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true);
1787*6777b538SAndroid Build Coastguard Worker }
1788*6777b538SAndroid Build Coastguard Worker
1789*6777b538SAndroid Build Coastguard Worker // NO_THREAD_SAFETY_ANALYSIS: Conditional locking above.
1790*6777b538SAndroid Build Coastguard Worker if (trace_event) {
1791*6777b538SAndroid Build Coastguard Worker trace_event->Reset(thread_id, offset_event_timestamp, thread_timestamp,
1792*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id,
1793*6777b538SAndroid Build Coastguard Worker bind_id, args, flags);
1794*6777b538SAndroid Build Coastguard Worker }
1795*6777b538SAndroid Build Coastguard Worker
1796*6777b538SAndroid Build Coastguard Worker if (trace_options() & kInternalEchoToConsole) {
1797*6777b538SAndroid Build Coastguard Worker console_message = EventToConsoleMessage(
1798*6777b538SAndroid Build Coastguard Worker phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase,
1799*6777b538SAndroid Build Coastguard Worker timestamp, trace_event);
1800*6777b538SAndroid Build Coastguard Worker }
1801*6777b538SAndroid Build Coastguard Worker }
1802*6777b538SAndroid Build Coastguard Worker
1803*6777b538SAndroid Build Coastguard Worker if (!console_message.empty())
1804*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << console_message;
1805*6777b538SAndroid Build Coastguard Worker
1806*6777b538SAndroid Build Coastguard Worker return handle;
1807*6777b538SAndroid Build Coastguard Worker }
1808*6777b538SAndroid Build Coastguard Worker
AddMetadataEvent(const unsigned char * category_group_enabled,const char * name,TraceArguments * args,unsigned int flags)1809*6777b538SAndroid Build Coastguard Worker void TraceLog::AddMetadataEvent(const unsigned char* category_group_enabled,
1810*6777b538SAndroid Build Coastguard Worker const char* name,
1811*6777b538SAndroid Build Coastguard Worker TraceArguments* args,
1812*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
1813*6777b538SAndroid Build Coastguard Worker HEAP_PROFILER_SCOPED_IGNORE;
1814*6777b538SAndroid Build Coastguard Worker auto thread_id = base::PlatformThread::CurrentId();
1815*6777b538SAndroid Build Coastguard Worker ThreadTicks thread_now = ThreadNow();
1816*6777b538SAndroid Build Coastguard Worker TimeTicks now = OffsetNow();
1817*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
1818*6777b538SAndroid Build Coastguard Worker auto trace_event = std::make_unique<TraceEvent>(
1819*6777b538SAndroid Build Coastguard Worker thread_id, now, thread_now, TRACE_EVENT_PHASE_METADATA,
1820*6777b538SAndroid Build Coastguard Worker category_group_enabled, name,
1821*6777b538SAndroid Build Coastguard Worker trace_event_internal::kGlobalScope, // scope
1822*6777b538SAndroid Build Coastguard Worker trace_event_internal::kNoId, // id
1823*6777b538SAndroid Build Coastguard Worker trace_event_internal::kNoId, // bind_id
1824*6777b538SAndroid Build Coastguard Worker args, flags);
1825*6777b538SAndroid Build Coastguard Worker metadata_events_.push_back(std::move(trace_event));
1826*6777b538SAndroid Build Coastguard Worker }
1827*6777b538SAndroid Build Coastguard Worker
1828*6777b538SAndroid Build Coastguard Worker // May be called when a COMPELETE event ends and the unfinished event has been
1829*6777b538SAndroid Build Coastguard Worker // recycled (phase == TRACE_EVENT_PHASE_END and trace_event == NULL).
EventToConsoleMessage(char phase,const TimeTicks & timestamp,TraceEvent * trace_event)1830*6777b538SAndroid Build Coastguard Worker std::string TraceLog::EventToConsoleMessage(char phase,
1831*6777b538SAndroid Build Coastguard Worker const TimeTicks& timestamp,
1832*6777b538SAndroid Build Coastguard Worker TraceEvent* trace_event) {
1833*6777b538SAndroid Build Coastguard Worker HEAP_PROFILER_SCOPED_IGNORE;
1834*6777b538SAndroid Build Coastguard Worker AutoLock thread_info_lock(thread_info_lock_);
1835*6777b538SAndroid Build Coastguard Worker
1836*6777b538SAndroid Build Coastguard Worker // The caller should translate TRACE_EVENT_PHASE_COMPLETE to
1837*6777b538SAndroid Build Coastguard Worker // TRACE_EVENT_PHASE_BEGIN or TRACE_EVENT_END.
1838*6777b538SAndroid Build Coastguard Worker DCHECK(phase != TRACE_EVENT_PHASE_COMPLETE);
1839*6777b538SAndroid Build Coastguard Worker
1840*6777b538SAndroid Build Coastguard Worker TimeDelta duration;
1841*6777b538SAndroid Build Coastguard Worker auto thread_id =
1842*6777b538SAndroid Build Coastguard Worker trace_event ? trace_event->thread_id() : PlatformThread::CurrentId();
1843*6777b538SAndroid Build Coastguard Worker if (phase == TRACE_EVENT_PHASE_END) {
1844*6777b538SAndroid Build Coastguard Worker duration = timestamp - thread_event_start_times_[thread_id].top();
1845*6777b538SAndroid Build Coastguard Worker thread_event_start_times_[thread_id].pop();
1846*6777b538SAndroid Build Coastguard Worker }
1847*6777b538SAndroid Build Coastguard Worker
1848*6777b538SAndroid Build Coastguard Worker std::string thread_name = thread_names_[thread_id];
1849*6777b538SAndroid Build Coastguard Worker if (thread_colors_.find(thread_name) == thread_colors_.end()) {
1850*6777b538SAndroid Build Coastguard Worker size_t next_color = (thread_colors_.size() % 6) + 1;
1851*6777b538SAndroid Build Coastguard Worker thread_colors_[thread_name] = next_color;
1852*6777b538SAndroid Build Coastguard Worker }
1853*6777b538SAndroid Build Coastguard Worker
1854*6777b538SAndroid Build Coastguard Worker std::ostringstream log;
1855*6777b538SAndroid Build Coastguard Worker log << base::StringPrintf("%s: \x1b[0;3%" PRIuS "m", thread_name.c_str(),
1856*6777b538SAndroid Build Coastguard Worker thread_colors_[thread_name]);
1857*6777b538SAndroid Build Coastguard Worker
1858*6777b538SAndroid Build Coastguard Worker size_t depth = 0;
1859*6777b538SAndroid Build Coastguard Worker auto it = thread_event_start_times_.find(thread_id);
1860*6777b538SAndroid Build Coastguard Worker if (it != thread_event_start_times_.end())
1861*6777b538SAndroid Build Coastguard Worker depth = it->second.size();
1862*6777b538SAndroid Build Coastguard Worker
1863*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < depth; ++i)
1864*6777b538SAndroid Build Coastguard Worker log << "| ";
1865*6777b538SAndroid Build Coastguard Worker
1866*6777b538SAndroid Build Coastguard Worker if (trace_event)
1867*6777b538SAndroid Build Coastguard Worker trace_event->AppendPrettyPrinted(&log);
1868*6777b538SAndroid Build Coastguard Worker if (phase == TRACE_EVENT_PHASE_END)
1869*6777b538SAndroid Build Coastguard Worker log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF());
1870*6777b538SAndroid Build Coastguard Worker
1871*6777b538SAndroid Build Coastguard Worker log << "\x1b[0;m";
1872*6777b538SAndroid Build Coastguard Worker
1873*6777b538SAndroid Build Coastguard Worker if (phase == TRACE_EVENT_PHASE_BEGIN)
1874*6777b538SAndroid Build Coastguard Worker thread_event_start_times_[thread_id].push(timestamp);
1875*6777b538SAndroid Build Coastguard Worker
1876*6777b538SAndroid Build Coastguard Worker return log.str();
1877*6777b538SAndroid Build Coastguard Worker }
1878*6777b538SAndroid Build Coastguard Worker
UpdateTraceEventDuration(const unsigned char * category_group_enabled,const char * name,TraceEventHandle handle)1879*6777b538SAndroid Build Coastguard Worker void TraceLog::UpdateTraceEventDuration(
1880*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1881*6777b538SAndroid Build Coastguard Worker const char* name,
1882*6777b538SAndroid Build Coastguard Worker TraceEventHandle handle) {
1883*6777b538SAndroid Build Coastguard Worker if (!*category_group_enabled)
1884*6777b538SAndroid Build Coastguard Worker return;
1885*6777b538SAndroid Build Coastguard Worker
1886*6777b538SAndroid Build Coastguard Worker UpdateTraceEventDurationExplicit(
1887*6777b538SAndroid Build Coastguard Worker category_group_enabled, name, handle, base::PlatformThread::CurrentId(),
1888*6777b538SAndroid Build Coastguard Worker /*explicit_timestamps=*/false, OffsetNow(), ThreadNow());
1889*6777b538SAndroid Build Coastguard Worker }
1890*6777b538SAndroid Build Coastguard Worker
UpdateTraceEventDurationExplicit(const unsigned char * category_group_enabled,const char * name,TraceEventHandle handle,PlatformThreadId thread_id,bool explicit_timestamps,const TimeTicks & now,const ThreadTicks & thread_now)1891*6777b538SAndroid Build Coastguard Worker void TraceLog::UpdateTraceEventDurationExplicit(
1892*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1893*6777b538SAndroid Build Coastguard Worker const char* name,
1894*6777b538SAndroid Build Coastguard Worker TraceEventHandle handle,
1895*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id,
1896*6777b538SAndroid Build Coastguard Worker bool explicit_timestamps,
1897*6777b538SAndroid Build Coastguard Worker const TimeTicks& now,
1898*6777b538SAndroid Build Coastguard Worker const ThreadTicks& thread_now) {
1899*6777b538SAndroid Build Coastguard Worker if (!*category_group_enabled)
1900*6777b538SAndroid Build Coastguard Worker return;
1901*6777b538SAndroid Build Coastguard Worker
1902*6777b538SAndroid Build Coastguard Worker // Avoid re-entrance of AddTraceEvent. This may happen in GPU process when
1903*6777b538SAndroid Build Coastguard Worker // ECHO_TO_CONSOLE is enabled: AddTraceEvent -> LOG(ERROR) ->
1904*6777b538SAndroid Build Coastguard Worker // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ...
1905*6777b538SAndroid Build Coastguard Worker if (thread_is_in_trace_event) {
1906*6777b538SAndroid Build Coastguard Worker return;
1907*6777b538SAndroid Build Coastguard Worker }
1908*6777b538SAndroid Build Coastguard Worker const AutoReset<bool> resetter(&thread_is_in_trace_event, true);
1909*6777b538SAndroid Build Coastguard Worker
1910*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
1911*6777b538SAndroid Build Coastguard Worker // Generate an ETW event that marks the end of a complete event.
1912*6777b538SAndroid Build Coastguard Worker if (*category_group_enabled & TraceCategory::ENABLED_FOR_ETW_EXPORT)
1913*6777b538SAndroid Build Coastguard Worker TraceEventETWExport::AddCompleteEndEvent(category_group_enabled, name);
1914*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
1915*6777b538SAndroid Build Coastguard Worker
1916*6777b538SAndroid Build Coastguard Worker if (*category_group_enabled & TraceCategory::ENABLED_FOR_RECORDING) {
1917*6777b538SAndroid Build Coastguard Worker auto update_duration_override =
1918*6777b538SAndroid Build Coastguard Worker update_duration_override_.load(std::memory_order_relaxed);
1919*6777b538SAndroid Build Coastguard Worker if (update_duration_override) {
1920*6777b538SAndroid Build Coastguard Worker update_duration_override(category_group_enabled, name, handle, thread_id,
1921*6777b538SAndroid Build Coastguard Worker explicit_timestamps, now, thread_now);
1922*6777b538SAndroid Build Coastguard Worker return;
1923*6777b538SAndroid Build Coastguard Worker }
1924*6777b538SAndroid Build Coastguard Worker }
1925*6777b538SAndroid Build Coastguard Worker
1926*6777b538SAndroid Build Coastguard Worker std::string console_message;
1927*6777b538SAndroid Build Coastguard Worker if (*category_group_enabled & TraceCategory::ENABLED_FOR_RECORDING) {
1928*6777b538SAndroid Build Coastguard Worker OptionalAutoLock lock(&lock_);
1929*6777b538SAndroid Build Coastguard Worker
1930*6777b538SAndroid Build Coastguard Worker TraceEvent* trace_event = GetEventByHandleInternal(handle, &lock);
1931*6777b538SAndroid Build Coastguard Worker if (trace_event) {
1932*6777b538SAndroid Build Coastguard Worker DCHECK(trace_event->phase() == TRACE_EVENT_PHASE_COMPLETE);
1933*6777b538SAndroid Build Coastguard Worker
1934*6777b538SAndroid Build Coastguard Worker trace_event->UpdateDuration(now, thread_now);
1935*6777b538SAndroid Build Coastguard Worker }
1936*6777b538SAndroid Build Coastguard Worker
1937*6777b538SAndroid Build Coastguard Worker if (trace_options() & kInternalEchoToConsole) {
1938*6777b538SAndroid Build Coastguard Worker console_message =
1939*6777b538SAndroid Build Coastguard Worker EventToConsoleMessage(TRACE_EVENT_PHASE_END, now, trace_event);
1940*6777b538SAndroid Build Coastguard Worker }
1941*6777b538SAndroid Build Coastguard Worker }
1942*6777b538SAndroid Build Coastguard Worker
1943*6777b538SAndroid Build Coastguard Worker if (!console_message.empty())
1944*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << console_message;
1945*6777b538SAndroid Build Coastguard Worker }
1946*6777b538SAndroid Build Coastguard Worker
MangleEventId(uint64_t id)1947*6777b538SAndroid Build Coastguard Worker uint64_t TraceLog::MangleEventId(uint64_t id) {
1948*6777b538SAndroid Build Coastguard Worker return id ^ process_id_hash_;
1949*6777b538SAndroid Build Coastguard Worker }
1950*6777b538SAndroid Build Coastguard Worker
1951*6777b538SAndroid Build Coastguard Worker template <typename T>
AddMetadataEventWhileLocked(PlatformThreadId thread_id,const char * metadata_name,const char * arg_name,const T & value)1952*6777b538SAndroid Build Coastguard Worker void TraceLog::AddMetadataEventWhileLocked(PlatformThreadId thread_id,
1953*6777b538SAndroid Build Coastguard Worker const char* metadata_name,
1954*6777b538SAndroid Build Coastguard Worker const char* arg_name,
1955*6777b538SAndroid Build Coastguard Worker const T& value) {
1956*6777b538SAndroid Build Coastguard Worker auto trace_event_override =
1957*6777b538SAndroid Build Coastguard Worker add_trace_event_override_.load(std::memory_order_relaxed);
1958*6777b538SAndroid Build Coastguard Worker if (trace_event_override) {
1959*6777b538SAndroid Build Coastguard Worker TraceEvent trace_event;
1960*6777b538SAndroid Build Coastguard Worker InitializeMetadataEvent(&trace_event, thread_id, metadata_name, arg_name,
1961*6777b538SAndroid Build Coastguard Worker value);
1962*6777b538SAndroid Build Coastguard Worker trace_event_override(&trace_event, /*thread_will_flush=*/true, nullptr);
1963*6777b538SAndroid Build Coastguard Worker } else {
1964*6777b538SAndroid Build Coastguard Worker InitializeMetadataEvent(
1965*6777b538SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false), thread_id,
1966*6777b538SAndroid Build Coastguard Worker metadata_name, arg_name, value);
1967*6777b538SAndroid Build Coastguard Worker }
1968*6777b538SAndroid Build Coastguard Worker }
1969*6777b538SAndroid Build Coastguard Worker
AddMetadataEventsWhileLocked()1970*6777b538SAndroid Build Coastguard Worker void TraceLog::AddMetadataEventsWhileLocked() {
1971*6777b538SAndroid Build Coastguard Worker auto trace_event_override =
1972*6777b538SAndroid Build Coastguard Worker add_trace_event_override_.load(std::memory_order_relaxed);
1973*6777b538SAndroid Build Coastguard Worker
1974*6777b538SAndroid Build Coastguard Worker // Move metadata added by |AddMetadataEvent| into the trace log.
1975*6777b538SAndroid Build Coastguard Worker if (trace_event_override) {
1976*6777b538SAndroid Build Coastguard Worker while (!metadata_events_.empty()) {
1977*6777b538SAndroid Build Coastguard Worker trace_event_override(metadata_events_.back().get(),
1978*6777b538SAndroid Build Coastguard Worker /*thread_will_flush=*/true, nullptr);
1979*6777b538SAndroid Build Coastguard Worker metadata_events_.pop_back();
1980*6777b538SAndroid Build Coastguard Worker }
1981*6777b538SAndroid Build Coastguard Worker } else {
1982*6777b538SAndroid Build Coastguard Worker while (!metadata_events_.empty()) {
1983*6777b538SAndroid Build Coastguard Worker TraceEvent* event =
1984*6777b538SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false);
1985*6777b538SAndroid Build Coastguard Worker *event = std::move(*metadata_events_.back());
1986*6777b538SAndroid Build Coastguard Worker metadata_events_.pop_back();
1987*6777b538SAndroid Build Coastguard Worker }
1988*6777b538SAndroid Build Coastguard Worker }
1989*6777b538SAndroid Build Coastguard Worker
1990*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_NACL) // NaCl shouldn't expose the process id.
1991*6777b538SAndroid Build Coastguard Worker AddMetadataEventWhileLocked(0, "num_cpus", "number",
1992*6777b538SAndroid Build Coastguard Worker base::SysInfo::NumberOfProcessors());
1993*6777b538SAndroid Build Coastguard Worker #endif
1994*6777b538SAndroid Build Coastguard Worker
1995*6777b538SAndroid Build Coastguard Worker auto current_thread_id = base::PlatformThread::CurrentId();
1996*6777b538SAndroid Build Coastguard Worker if (process_sort_index_ != 0) {
1997*6777b538SAndroid Build Coastguard Worker AddMetadataEventWhileLocked(current_thread_id, "process_sort_index",
1998*6777b538SAndroid Build Coastguard Worker "sort_index", process_sort_index_);
1999*6777b538SAndroid Build Coastguard Worker }
2000*6777b538SAndroid Build Coastguard Worker
2001*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
2002*6777b538SAndroid Build Coastguard Worker AddMetadataEventWhileLocked(current_thread_id, "chrome_library_address",
2003*6777b538SAndroid Build Coastguard Worker "start_address",
2004*6777b538SAndroid Build Coastguard Worker base::StringPrintf("%p", &__executable_start));
2005*6777b538SAndroid Build Coastguard Worker base::debug::ElfBuildIdBuffer build_id;
2006*6777b538SAndroid Build Coastguard Worker size_t build_id_length =
2007*6777b538SAndroid Build Coastguard Worker base::debug::ReadElfBuildId(&__executable_start, true, build_id);
2008*6777b538SAndroid Build Coastguard Worker if (build_id_length > 0) {
2009*6777b538SAndroid Build Coastguard Worker AddMetadataEventWhileLocked(current_thread_id, "chrome_library_module",
2010*6777b538SAndroid Build Coastguard Worker "id", std::string(build_id));
2011*6777b538SAndroid Build Coastguard Worker }
2012*6777b538SAndroid Build Coastguard Worker #endif
2013*6777b538SAndroid Build Coastguard Worker
2014*6777b538SAndroid Build Coastguard Worker if (!process_labels_.empty()) {
2015*6777b538SAndroid Build Coastguard Worker std::vector<std::string_view> labels;
2016*6777b538SAndroid Build Coastguard Worker for (const auto& it : process_labels_)
2017*6777b538SAndroid Build Coastguard Worker labels.push_back(it.second);
2018*6777b538SAndroid Build Coastguard Worker AddMetadataEventWhileLocked(current_thread_id, "process_labels", "labels",
2019*6777b538SAndroid Build Coastguard Worker base::JoinString(labels, ","));
2020*6777b538SAndroid Build Coastguard Worker }
2021*6777b538SAndroid Build Coastguard Worker
2022*6777b538SAndroid Build Coastguard Worker // Thread sort indices.
2023*6777b538SAndroid Build Coastguard Worker for (const auto& it : thread_sort_indices_) {
2024*6777b538SAndroid Build Coastguard Worker if (it.second == 0)
2025*6777b538SAndroid Build Coastguard Worker continue;
2026*6777b538SAndroid Build Coastguard Worker AddMetadataEventWhileLocked(it.first, "thread_sort_index", "sort_index",
2027*6777b538SAndroid Build Coastguard Worker it.second);
2028*6777b538SAndroid Build Coastguard Worker }
2029*6777b538SAndroid Build Coastguard Worker
2030*6777b538SAndroid Build Coastguard Worker // If buffer is full, add a metadata record to report this.
2031*6777b538SAndroid Build Coastguard Worker if (!buffer_limit_reached_timestamp_.is_null()) {
2032*6777b538SAndroid Build Coastguard Worker AddMetadataEventWhileLocked(current_thread_id, "trace_buffer_overflowed",
2033*6777b538SAndroid Build Coastguard Worker "overflowed_at_ts",
2034*6777b538SAndroid Build Coastguard Worker buffer_limit_reached_timestamp_);
2035*6777b538SAndroid Build Coastguard Worker }
2036*6777b538SAndroid Build Coastguard Worker }
2037*6777b538SAndroid Build Coastguard Worker
GetEventByHandle(TraceEventHandle handle)2038*6777b538SAndroid Build Coastguard Worker TraceEvent* TraceLog::GetEventByHandle(TraceEventHandle handle) {
2039*6777b538SAndroid Build Coastguard Worker return GetEventByHandleInternal(handle, nullptr);
2040*6777b538SAndroid Build Coastguard Worker }
2041*6777b538SAndroid Build Coastguard Worker
GetEventByHandleInternal(TraceEventHandle handle,OptionalAutoLock * lock)2042*6777b538SAndroid Build Coastguard Worker TraceEvent* TraceLog::GetEventByHandleInternal(TraceEventHandle handle,
2043*6777b538SAndroid Build Coastguard Worker OptionalAutoLock* lock)
2044*6777b538SAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS {
2045*6777b538SAndroid Build Coastguard Worker if (!handle.chunk_seq)
2046*6777b538SAndroid Build Coastguard Worker return nullptr;
2047*6777b538SAndroid Build Coastguard Worker
2048*6777b538SAndroid Build Coastguard Worker DCHECK(handle.chunk_seq);
2049*6777b538SAndroid Build Coastguard Worker DCHECK(handle.chunk_index <= TraceBufferChunk::kMaxChunkIndex);
2050*6777b538SAndroid Build Coastguard Worker DCHECK(handle.event_index <= TraceBufferChunk::kTraceBufferChunkSize - 1);
2051*6777b538SAndroid Build Coastguard Worker
2052*6777b538SAndroid Build Coastguard Worker if (thread_local_event_buffer) {
2053*6777b538SAndroid Build Coastguard Worker TraceEvent* trace_event =
2054*6777b538SAndroid Build Coastguard Worker thread_local_event_buffer->GetEventByHandle(handle);
2055*6777b538SAndroid Build Coastguard Worker if (trace_event)
2056*6777b538SAndroid Build Coastguard Worker return trace_event;
2057*6777b538SAndroid Build Coastguard Worker }
2058*6777b538SAndroid Build Coastguard Worker
2059*6777b538SAndroid Build Coastguard Worker // The event has been out-of-control of the thread local buffer.
2060*6777b538SAndroid Build Coastguard Worker // Try to get the event from the main buffer with a lock.
2061*6777b538SAndroid Build Coastguard Worker // NO_THREAD_SAFETY_ANALYSIS: runtime-dependent locking here.
2062*6777b538SAndroid Build Coastguard Worker if (lock)
2063*6777b538SAndroid Build Coastguard Worker lock->EnsureAcquired();
2064*6777b538SAndroid Build Coastguard Worker
2065*6777b538SAndroid Build Coastguard Worker if (thread_shared_chunk_ &&
2066*6777b538SAndroid Build Coastguard Worker handle.chunk_index == thread_shared_chunk_index_) {
2067*6777b538SAndroid Build Coastguard Worker return handle.chunk_seq == thread_shared_chunk_->seq()
2068*6777b538SAndroid Build Coastguard Worker ? thread_shared_chunk_->GetEventAt(handle.event_index)
2069*6777b538SAndroid Build Coastguard Worker : nullptr;
2070*6777b538SAndroid Build Coastguard Worker }
2071*6777b538SAndroid Build Coastguard Worker
2072*6777b538SAndroid Build Coastguard Worker return logged_events_->GetEventByHandle(handle);
2073*6777b538SAndroid Build Coastguard Worker }
2074*6777b538SAndroid Build Coastguard Worker
SetProcessID(ProcessId process_id)2075*6777b538SAndroid Build Coastguard Worker void TraceLog::SetProcessID(ProcessId process_id) {
2076*6777b538SAndroid Build Coastguard Worker process_id_ = process_id;
2077*6777b538SAndroid Build Coastguard Worker // Create a FNV hash from the process ID for XORing.
2078*6777b538SAndroid Build Coastguard Worker // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details.
2079*6777b538SAndroid Build Coastguard Worker const uint64_t kOffsetBasis = 14695981039346656037ull;
2080*6777b538SAndroid Build Coastguard Worker const uint64_t kFnvPrime = 1099511628211ull;
2081*6777b538SAndroid Build Coastguard Worker const uint64_t pid = static_cast<uint64_t>(process_id_);
2082*6777b538SAndroid Build Coastguard Worker process_id_hash_ = (kOffsetBasis ^ pid) * kFnvPrime;
2083*6777b538SAndroid Build Coastguard Worker }
2084*6777b538SAndroid Build Coastguard Worker
SetProcessSortIndex(int sort_index)2085*6777b538SAndroid Build Coastguard Worker void TraceLog::SetProcessSortIndex(int sort_index) {
2086*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
2087*6777b538SAndroid Build Coastguard Worker process_sort_index_ = sort_index;
2088*6777b538SAndroid Build Coastguard Worker }
2089*6777b538SAndroid Build Coastguard Worker
OnSetProcessName(const std::string & process_name)2090*6777b538SAndroid Build Coastguard Worker void TraceLog::OnSetProcessName(const std::string& process_name) {
2091*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
2092*6777b538SAndroid Build Coastguard Worker if (perfetto::Tracing::IsInitialized()) {
2093*6777b538SAndroid Build Coastguard Worker auto track = perfetto::ProcessTrack::Current();
2094*6777b538SAndroid Build Coastguard Worker auto desc = track.Serialize();
2095*6777b538SAndroid Build Coastguard Worker desc.mutable_process()->set_process_name(process_name);
2096*6777b538SAndroid Build Coastguard Worker desc.mutable_process()->set_pid(static_cast<int>(process_id_));
2097*6777b538SAndroid Build Coastguard Worker TrackEvent::SetTrackDescriptor(track, std::move(desc));
2098*6777b538SAndroid Build Coastguard Worker }
2099*6777b538SAndroid Build Coastguard Worker #endif
2100*6777b538SAndroid Build Coastguard Worker }
2101*6777b538SAndroid Build Coastguard Worker
GetNewProcessLabelId()2102*6777b538SAndroid Build Coastguard Worker int TraceLog::GetNewProcessLabelId() {
2103*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
2104*6777b538SAndroid Build Coastguard Worker return next_process_label_id_++;
2105*6777b538SAndroid Build Coastguard Worker }
2106*6777b538SAndroid Build Coastguard Worker
UpdateProcessLabel(int label_id,const std::string & current_label)2107*6777b538SAndroid Build Coastguard Worker void TraceLog::UpdateProcessLabel(int label_id,
2108*6777b538SAndroid Build Coastguard Worker const std::string& current_label) {
2109*6777b538SAndroid Build Coastguard Worker if (!current_label.length())
2110*6777b538SAndroid Build Coastguard Worker return RemoveProcessLabel(label_id);
2111*6777b538SAndroid Build Coastguard Worker
2112*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
2113*6777b538SAndroid Build Coastguard Worker if (perfetto::Tracing::IsInitialized()) {
2114*6777b538SAndroid Build Coastguard Worker auto track = perfetto::ProcessTrack::Current();
2115*6777b538SAndroid Build Coastguard Worker auto desc = track.Serialize();
2116*6777b538SAndroid Build Coastguard Worker desc.mutable_process()->add_process_labels(current_label);
2117*6777b538SAndroid Build Coastguard Worker TrackEvent::SetTrackDescriptor(track, std::move(desc));
2118*6777b538SAndroid Build Coastguard Worker }
2119*6777b538SAndroid Build Coastguard Worker #endif
2120*6777b538SAndroid Build Coastguard Worker
2121*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
2122*6777b538SAndroid Build Coastguard Worker process_labels_[label_id] = current_label;
2123*6777b538SAndroid Build Coastguard Worker }
2124*6777b538SAndroid Build Coastguard Worker
RemoveProcessLabel(int label_id)2125*6777b538SAndroid Build Coastguard Worker void TraceLog::RemoveProcessLabel(int label_id) {
2126*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
2127*6777b538SAndroid Build Coastguard Worker process_labels_.erase(label_id);
2128*6777b538SAndroid Build Coastguard Worker }
2129*6777b538SAndroid Build Coastguard Worker
SetThreadSortIndex(PlatformThreadId thread_id,int sort_index)2130*6777b538SAndroid Build Coastguard Worker void TraceLog::SetThreadSortIndex(PlatformThreadId thread_id, int sort_index) {
2131*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
2132*6777b538SAndroid Build Coastguard Worker thread_sort_indices_[thread_id] = sort_index;
2133*6777b538SAndroid Build Coastguard Worker }
2134*6777b538SAndroid Build Coastguard Worker
2135*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
SetTimeOffset(TimeDelta offset)2136*6777b538SAndroid Build Coastguard Worker void TraceLog::SetTimeOffset(TimeDelta offset) {
2137*6777b538SAndroid Build Coastguard Worker time_offset_ = offset;
2138*6777b538SAndroid Build Coastguard Worker }
2139*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
2140*6777b538SAndroid Build Coastguard Worker
GetObserverCountForTest() const2141*6777b538SAndroid Build Coastguard Worker size_t TraceLog::GetObserverCountForTest() const {
2142*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
2143*6777b538SAndroid Build Coastguard Worker return enabled_state_observers_.size();
2144*6777b538SAndroid Build Coastguard Worker }
2145*6777b538SAndroid Build Coastguard Worker
SetCurrentThreadBlocksMessageLoop()2146*6777b538SAndroid Build Coastguard Worker void TraceLog::SetCurrentThreadBlocksMessageLoop() {
2147*6777b538SAndroid Build Coastguard Worker thread_blocks_message_loop = true;
2148*6777b538SAndroid Build Coastguard Worker // This will flush the thread local buffer.
2149*6777b538SAndroid Build Coastguard Worker delete thread_local_event_buffer;
2150*6777b538SAndroid Build Coastguard Worker }
2151*6777b538SAndroid Build Coastguard Worker
CreateTraceBuffer()2152*6777b538SAndroid Build Coastguard Worker TraceBuffer* TraceLog::CreateTraceBuffer() {
2153*6777b538SAndroid Build Coastguard Worker HEAP_PROFILER_SCOPED_IGNORE;
2154*6777b538SAndroid Build Coastguard Worker InternalTraceOptions options = trace_options();
2155*6777b538SAndroid Build Coastguard Worker const size_t config_buffer_chunks =
2156*6777b538SAndroid Build Coastguard Worker trace_config_.GetTraceBufferSizeInEvents() / kTraceBufferChunkSize;
2157*6777b538SAndroid Build Coastguard Worker if (options & kInternalRecordContinuously) {
2158*6777b538SAndroid Build Coastguard Worker return TraceBuffer::CreateTraceBufferRingBuffer(
2159*6777b538SAndroid Build Coastguard Worker config_buffer_chunks > 0 ? config_buffer_chunks
2160*6777b538SAndroid Build Coastguard Worker : kTraceEventRingBufferChunks);
2161*6777b538SAndroid Build Coastguard Worker }
2162*6777b538SAndroid Build Coastguard Worker if (options & kInternalEchoToConsole) {
2163*6777b538SAndroid Build Coastguard Worker return TraceBuffer::CreateTraceBufferRingBuffer(
2164*6777b538SAndroid Build Coastguard Worker config_buffer_chunks > 0 ? config_buffer_chunks
2165*6777b538SAndroid Build Coastguard Worker : kEchoToConsoleTraceEventBufferChunks);
2166*6777b538SAndroid Build Coastguard Worker }
2167*6777b538SAndroid Build Coastguard Worker if (options & kInternalRecordAsMuchAsPossible) {
2168*6777b538SAndroid Build Coastguard Worker return TraceBuffer::CreateTraceBufferVectorOfSize(
2169*6777b538SAndroid Build Coastguard Worker config_buffer_chunks > 0 ? config_buffer_chunks
2170*6777b538SAndroid Build Coastguard Worker : kTraceEventVectorBigBufferChunks);
2171*6777b538SAndroid Build Coastguard Worker }
2172*6777b538SAndroid Build Coastguard Worker return TraceBuffer::CreateTraceBufferVectorOfSize(
2173*6777b538SAndroid Build Coastguard Worker config_buffer_chunks > 0 ? config_buffer_chunks
2174*6777b538SAndroid Build Coastguard Worker : kTraceEventVectorBufferChunks);
2175*6777b538SAndroid Build Coastguard Worker }
2176*6777b538SAndroid Build Coastguard Worker
2177*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
UpdateETWCategoryGroupEnabledFlags()2178*6777b538SAndroid Build Coastguard Worker void TraceLog::UpdateETWCategoryGroupEnabledFlags() {
2179*6777b538SAndroid Build Coastguard Worker // Go through each category and set/clear the ETW bit depending on whether the
2180*6777b538SAndroid Build Coastguard Worker // category is enabled.
2181*6777b538SAndroid Build Coastguard Worker for (TraceCategory& category : CategoryRegistry::GetAllCategories()) {
2182*6777b538SAndroid Build Coastguard Worker if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled(
2183*6777b538SAndroid Build Coastguard Worker category.name())) {
2184*6777b538SAndroid Build Coastguard Worker category.set_state_flag(TraceCategory::ENABLED_FOR_ETW_EXPORT);
2185*6777b538SAndroid Build Coastguard Worker } else {
2186*6777b538SAndroid Build Coastguard Worker category.clear_state_flag(TraceCategory::ENABLED_FOR_ETW_EXPORT);
2187*6777b538SAndroid Build Coastguard Worker }
2188*6777b538SAndroid Build Coastguard Worker }
2189*6777b538SAndroid Build Coastguard Worker }
2190*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
2191*6777b538SAndroid Build Coastguard Worker
SetTraceBufferForTesting(std::unique_ptr<TraceBuffer> trace_buffer)2192*6777b538SAndroid Build Coastguard Worker void TraceLog::SetTraceBufferForTesting(
2193*6777b538SAndroid Build Coastguard Worker std::unique_ptr<TraceBuffer> trace_buffer) {
2194*6777b538SAndroid Build Coastguard Worker AutoLock lock(lock_);
2195*6777b538SAndroid Build Coastguard Worker logged_events_ = std::move(trace_buffer);
2196*6777b538SAndroid Build Coastguard Worker }
2197*6777b538SAndroid Build Coastguard Worker
2198*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
OnSetup(const perfetto::DataSourceBase::SetupArgs & args)2199*6777b538SAndroid Build Coastguard Worker void TraceLog::OnSetup(const perfetto::DataSourceBase::SetupArgs& args) {
2200*6777b538SAndroid Build Coastguard Worker AutoLock lock(track_event_lock_);
2201*6777b538SAndroid Build Coastguard Worker track_event_sessions_.emplace_back(args.internal_instance_index, *args.config,
2202*6777b538SAndroid Build Coastguard Worker args.backend_type);
2203*6777b538SAndroid Build Coastguard Worker }
2204*6777b538SAndroid Build Coastguard Worker
OnStart(const perfetto::DataSourceBase::StartArgs &)2205*6777b538SAndroid Build Coastguard Worker void TraceLog::OnStart(const perfetto::DataSourceBase::StartArgs&) {
2206*6777b538SAndroid Build Coastguard Worker ++active_track_event_sessions_;
2207*6777b538SAndroid Build Coastguard Worker // Legacy observers don't support multiple tracing sessions. So we only
2208*6777b538SAndroid Build Coastguard Worker // notify them about the first one.
2209*6777b538SAndroid Build Coastguard Worker if (active_track_event_sessions_ > 1) {
2210*6777b538SAndroid Build Coastguard Worker return;
2211*6777b538SAndroid Build Coastguard Worker }
2212*6777b538SAndroid Build Coastguard Worker
2213*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
2214*6777b538SAndroid Build Coastguard Worker for (EnabledStateObserver* observer : enabled_state_observers_)
2215*6777b538SAndroid Build Coastguard Worker observer->OnTraceLogEnabled();
2216*6777b538SAndroid Build Coastguard Worker for (const auto& it : async_observers_) {
2217*6777b538SAndroid Build Coastguard Worker it.second.task_runner->PostTask(
2218*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&AsyncEnabledStateObserver::OnTraceLogEnabled,
2219*6777b538SAndroid Build Coastguard Worker it.second.observer));
2220*6777b538SAndroid Build Coastguard Worker }
2221*6777b538SAndroid Build Coastguard Worker }
2222*6777b538SAndroid Build Coastguard Worker
OnStop(const perfetto::DataSourceBase::StopArgs & args)2223*6777b538SAndroid Build Coastguard Worker void TraceLog::OnStop(const perfetto::DataSourceBase::StopArgs& args) {
2224*6777b538SAndroid Build Coastguard Worker {
2225*6777b538SAndroid Build Coastguard Worker // We can't use |lock_| because OnStop() can be called from within
2226*6777b538SAndroid Build Coastguard Worker // SetDisabled(). We also can't use |observers_lock_|, because observers
2227*6777b538SAndroid Build Coastguard Worker // below can call into IsEnabled(), which needs to access
2228*6777b538SAndroid Build Coastguard Worker // |track_event_sessions_|. So we use a separate lock.
2229*6777b538SAndroid Build Coastguard Worker AutoLock track_event_lock(track_event_lock_);
2230*6777b538SAndroid Build Coastguard Worker std::erase_if(track_event_sessions_, [&args](
2231*6777b538SAndroid Build Coastguard Worker const TrackEventSession& session) {
2232*6777b538SAndroid Build Coastguard Worker return session.internal_instance_index == args.internal_instance_index;
2233*6777b538SAndroid Build Coastguard Worker });
2234*6777b538SAndroid Build Coastguard Worker }
2235*6777b538SAndroid Build Coastguard Worker
2236*6777b538SAndroid Build Coastguard Worker --active_track_event_sessions_;
2237*6777b538SAndroid Build Coastguard Worker // Legacy observers don't support multiple tracing sessions. So we only
2238*6777b538SAndroid Build Coastguard Worker // notify them when the last one stopped.
2239*6777b538SAndroid Build Coastguard Worker if (active_track_event_sessions_ > 0) {
2240*6777b538SAndroid Build Coastguard Worker return;
2241*6777b538SAndroid Build Coastguard Worker }
2242*6777b538SAndroid Build Coastguard Worker
2243*6777b538SAndroid Build Coastguard Worker AutoLock lock(observers_lock_);
2244*6777b538SAndroid Build Coastguard Worker for (base::trace_event::TraceLog::EnabledStateObserver* it :
2245*6777b538SAndroid Build Coastguard Worker enabled_state_observers_) {
2246*6777b538SAndroid Build Coastguard Worker it->OnTraceLogDisabled();
2247*6777b538SAndroid Build Coastguard Worker }
2248*6777b538SAndroid Build Coastguard Worker for (const auto& it : async_observers_) {
2249*6777b538SAndroid Build Coastguard Worker it.second.task_runner->PostTask(
2250*6777b538SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&AsyncEnabledStateObserver::OnTraceLogDisabled,
2251*6777b538SAndroid Build Coastguard Worker it.second.observer));
2252*6777b538SAndroid Build Coastguard Worker }
2253*6777b538SAndroid Build Coastguard Worker }
2254*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
2255*6777b538SAndroid Build Coastguard Worker
EstimateTraceMemoryOverhead(TraceEventMemoryOverhead * overhead)2256*6777b538SAndroid Build Coastguard Worker void ConvertableToTraceFormat::EstimateTraceMemoryOverhead(
2257*6777b538SAndroid Build Coastguard Worker TraceEventMemoryOverhead* overhead) {
2258*6777b538SAndroid Build Coastguard Worker overhead->Add(TraceEventMemoryOverhead::kConvertableToTraceFormat,
2259*6777b538SAndroid Build Coastguard Worker sizeof(*this));
2260*6777b538SAndroid Build Coastguard Worker }
2261*6777b538SAndroid Build Coastguard Worker
2262*6777b538SAndroid Build Coastguard Worker } // namespace trace_event
2263*6777b538SAndroid Build Coastguard Worker } // namespace base
2264*6777b538SAndroid Build Coastguard Worker
2265*6777b538SAndroid Build Coastguard Worker namespace trace_event_internal {
2266*6777b538SAndroid Build Coastguard Worker
AddTraceEvent(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,base::trace_event::TraceArguments * args,unsigned int flags)2267*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceEventHandle AddTraceEvent(
2268*6777b538SAndroid Build Coastguard Worker char phase,
2269*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
2270*6777b538SAndroid Build Coastguard Worker const char* name,
2271*6777b538SAndroid Build Coastguard Worker const char* scope,
2272*6777b538SAndroid Build Coastguard Worker uint64_t id,
2273*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceArguments* args,
2274*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
2275*6777b538SAndroid Build Coastguard Worker return base::trace_event::TraceLog::GetInstance()->AddTraceEvent(
2276*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id, args, flags);
2277*6777b538SAndroid Build Coastguard Worker }
2278*6777b538SAndroid Build Coastguard Worker
AddTraceEventWithBindId(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,uint64_t bind_id,base::trace_event::TraceArguments * args,unsigned int flags)2279*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceEventHandle AddTraceEventWithBindId(
2280*6777b538SAndroid Build Coastguard Worker char phase,
2281*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
2282*6777b538SAndroid Build Coastguard Worker const char* name,
2283*6777b538SAndroid Build Coastguard Worker const char* scope,
2284*6777b538SAndroid Build Coastguard Worker uint64_t id,
2285*6777b538SAndroid Build Coastguard Worker uint64_t bind_id,
2286*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceArguments* args,
2287*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
2288*6777b538SAndroid Build Coastguard Worker return base::trace_event::TraceLog::GetInstance()->AddTraceEventWithBindId(
2289*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id, bind_id, args, flags);
2290*6777b538SAndroid Build Coastguard Worker }
2291*6777b538SAndroid Build Coastguard Worker
AddTraceEventWithProcessId(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,base::ProcessId process_id,base::trace_event::TraceArguments * args,unsigned int flags)2292*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceEventHandle AddTraceEventWithProcessId(
2293*6777b538SAndroid Build Coastguard Worker char phase,
2294*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
2295*6777b538SAndroid Build Coastguard Worker const char* name,
2296*6777b538SAndroid Build Coastguard Worker const char* scope,
2297*6777b538SAndroid Build Coastguard Worker uint64_t id,
2298*6777b538SAndroid Build Coastguard Worker base::ProcessId process_id,
2299*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceArguments* args,
2300*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
2301*6777b538SAndroid Build Coastguard Worker return base::trace_event::TraceLog::GetInstance()->AddTraceEventWithProcessId(
2302*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id, process_id, args, flags);
2303*6777b538SAndroid Build Coastguard Worker }
2304*6777b538SAndroid Build Coastguard Worker
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,base::trace_event::TraceArguments * args,unsigned int flags)2305*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
2306*6777b538SAndroid Build Coastguard Worker char phase,
2307*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
2308*6777b538SAndroid Build Coastguard Worker const char* name,
2309*6777b538SAndroid Build Coastguard Worker const char* scope,
2310*6777b538SAndroid Build Coastguard Worker uint64_t id,
2311*6777b538SAndroid Build Coastguard Worker base::PlatformThreadId thread_id,
2312*6777b538SAndroid Build Coastguard Worker const base::TimeTicks& timestamp,
2313*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceArguments* args,
2314*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
2315*6777b538SAndroid Build Coastguard Worker return base::trace_event::TraceLog::GetInstance()
2316*6777b538SAndroid Build Coastguard Worker ->AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled,
2317*6777b538SAndroid Build Coastguard Worker name, scope, id, thread_id,
2318*6777b538SAndroid Build Coastguard Worker timestamp, args, flags);
2319*6777b538SAndroid Build Coastguard Worker }
2320*6777b538SAndroid Build Coastguard Worker
AddTraceEventWithThreadIdAndTimestamp(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,uint64_t id,uint64_t bind_id,base::PlatformThreadId thread_id,const base::TimeTicks & timestamp,base::trace_event::TraceArguments * args,unsigned int flags)2321*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(
2322*6777b538SAndroid Build Coastguard Worker char phase,
2323*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
2324*6777b538SAndroid Build Coastguard Worker const char* name,
2325*6777b538SAndroid Build Coastguard Worker const char* scope,
2326*6777b538SAndroid Build Coastguard Worker uint64_t id,
2327*6777b538SAndroid Build Coastguard Worker uint64_t bind_id,
2328*6777b538SAndroid Build Coastguard Worker base::PlatformThreadId thread_id,
2329*6777b538SAndroid Build Coastguard Worker const base::TimeTicks& timestamp,
2330*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceArguments* args,
2331*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
2332*6777b538SAndroid Build Coastguard Worker return base::trace_event::TraceLog::GetInstance()
2333*6777b538SAndroid Build Coastguard Worker ->AddTraceEventWithThreadIdAndTimestamp(
2334*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id, bind_id, thread_id,
2335*6777b538SAndroid Build Coastguard Worker timestamp, args, flags);
2336*6777b538SAndroid Build Coastguard Worker }
2337*6777b538SAndroid Build Coastguard Worker
AddTraceEventWithThreadIdAndTimestamps(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,const base::ThreadTicks & thread_timestamp,unsigned int flags)2338*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamps(
2339*6777b538SAndroid Build Coastguard Worker char phase,
2340*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
2341*6777b538SAndroid Build Coastguard Worker const char* name,
2342*6777b538SAndroid Build Coastguard Worker const char* scope,
2343*6777b538SAndroid Build Coastguard Worker uint64_t id,
2344*6777b538SAndroid Build Coastguard Worker base::PlatformThreadId thread_id,
2345*6777b538SAndroid Build Coastguard Worker const base::TimeTicks& timestamp,
2346*6777b538SAndroid Build Coastguard Worker const base::ThreadTicks& thread_timestamp,
2347*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
2348*6777b538SAndroid Build Coastguard Worker return base::trace_event::TraceLog::GetInstance()
2349*6777b538SAndroid Build Coastguard Worker ->AddTraceEventWithThreadIdAndTimestamps(
2350*6777b538SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id,
2351*6777b538SAndroid Build Coastguard Worker /*bind_id=*/trace_event_internal::kNoId, thread_id, timestamp,
2352*6777b538SAndroid Build Coastguard Worker thread_timestamp, nullptr, flags);
2353*6777b538SAndroid Build Coastguard Worker }
2354*6777b538SAndroid Build Coastguard Worker
AddMetadataEvent(const unsigned char * category_group_enabled,const char * name,base::trace_event::TraceArguments * args,unsigned int flags)2355*6777b538SAndroid Build Coastguard Worker void AddMetadataEvent(const unsigned char* category_group_enabled,
2356*6777b538SAndroid Build Coastguard Worker const char* name,
2357*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceArguments* args,
2358*6777b538SAndroid Build Coastguard Worker unsigned int flags) {
2359*6777b538SAndroid Build Coastguard Worker return base::trace_event::TraceLog::GetInstance()->AddMetadataEvent(
2360*6777b538SAndroid Build Coastguard Worker category_group_enabled, name, args, flags);
2361*6777b538SAndroid Build Coastguard Worker }
2362*6777b538SAndroid Build Coastguard Worker
GetNumTracesRecorded()2363*6777b538SAndroid Build Coastguard Worker int GetNumTracesRecorded() {
2364*6777b538SAndroid Build Coastguard Worker return base::trace_event::TraceLog::GetInstance()->GetNumTracesRecorded();
2365*6777b538SAndroid Build Coastguard Worker }
2366*6777b538SAndroid Build Coastguard Worker
UpdateTraceEventDuration(const unsigned char * category_group_enabled,const char * name,base::trace_event::TraceEventHandle handle)2367*6777b538SAndroid Build Coastguard Worker void UpdateTraceEventDuration(const unsigned char* category_group_enabled,
2368*6777b538SAndroid Build Coastguard Worker const char* name,
2369*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceEventHandle handle) {
2370*6777b538SAndroid Build Coastguard Worker return base::trace_event::TraceLog::GetInstance()->UpdateTraceEventDuration(
2371*6777b538SAndroid Build Coastguard Worker category_group_enabled, name, handle);
2372*6777b538SAndroid Build Coastguard Worker }
2373*6777b538SAndroid Build Coastguard Worker
UpdateTraceEventDurationExplicit(const unsigned char * category_group_enabled,const char * name,base::trace_event::TraceEventHandle handle,base::PlatformThreadId thread_id,bool explicit_timestamps,const base::TimeTicks & now,const base::ThreadTicks & thread_now)2374*6777b538SAndroid Build Coastguard Worker void UpdateTraceEventDurationExplicit(
2375*6777b538SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
2376*6777b538SAndroid Build Coastguard Worker const char* name,
2377*6777b538SAndroid Build Coastguard Worker base::trace_event::TraceEventHandle handle,
2378*6777b538SAndroid Build Coastguard Worker base::PlatformThreadId thread_id,
2379*6777b538SAndroid Build Coastguard Worker bool explicit_timestamps,
2380*6777b538SAndroid Build Coastguard Worker const base::TimeTicks& now,
2381*6777b538SAndroid Build Coastguard Worker const base::ThreadTicks& thread_now) {
2382*6777b538SAndroid Build Coastguard Worker return base::trace_event::TraceLog::GetInstance()
2383*6777b538SAndroid Build Coastguard Worker ->UpdateTraceEventDurationExplicit(category_group_enabled, name, handle,
2384*6777b538SAndroid Build Coastguard Worker thread_id, explicit_timestamps, now,
2385*6777b538SAndroid Build Coastguard Worker thread_now);
2386*6777b538SAndroid Build Coastguard Worker }
2387*6777b538SAndroid Build Coastguard Worker
2388*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
ScopedTraceBinaryEfficient(const char * category_group,const char * name)2389*6777b538SAndroid Build Coastguard Worker ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient(
2390*6777b538SAndroid Build Coastguard Worker const char* category_group,
2391*6777b538SAndroid Build Coastguard Worker const char* name) {
2392*6777b538SAndroid Build Coastguard Worker // The single atom works because for now the category_group can only be "gpu".
2393*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(strcmp(category_group, "gpu"), 0);
2394*6777b538SAndroid Build Coastguard Worker static TRACE_EVENT_API_ATOMIC_WORD atomic = 0;
2395*6777b538SAndroid Build Coastguard Worker INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES(
2396*6777b538SAndroid Build Coastguard Worker category_group, atomic, category_group_enabled_);
2397*6777b538SAndroid Build Coastguard Worker name_ = name;
2398*6777b538SAndroid Build Coastguard Worker if (*category_group_enabled_) {
2399*6777b538SAndroid Build Coastguard Worker event_handle_ =
2400*6777b538SAndroid Build Coastguard Worker TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
2401*6777b538SAndroid Build Coastguard Worker TRACE_EVENT_PHASE_COMPLETE, category_group_enabled_, name,
2402*6777b538SAndroid Build Coastguard Worker trace_event_internal::kGlobalScope, // scope
2403*6777b538SAndroid Build Coastguard Worker trace_event_internal::kNoId, // id
2404*6777b538SAndroid Build Coastguard Worker base::PlatformThread::CurrentId(), // thread_id
2405*6777b538SAndroid Build Coastguard Worker TRACE_TIME_TICKS_NOW(), nullptr, TRACE_EVENT_FLAG_NONE);
2406*6777b538SAndroid Build Coastguard Worker }
2407*6777b538SAndroid Build Coastguard Worker }
2408*6777b538SAndroid Build Coastguard Worker
~ScopedTraceBinaryEfficient()2409*6777b538SAndroid Build Coastguard Worker ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
2410*6777b538SAndroid Build Coastguard Worker if (*category_group_enabled_) {
2411*6777b538SAndroid Build Coastguard Worker TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_,
2412*6777b538SAndroid Build Coastguard Worker event_handle_);
2413*6777b538SAndroid Build Coastguard Worker }
2414*6777b538SAndroid Build Coastguard Worker }
2415*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
2416*6777b538SAndroid Build Coastguard Worker
2417*6777b538SAndroid Build Coastguard Worker } // namespace trace_event_internal
2418