1*635a8641SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/trace_log.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <algorithm>
8*635a8641SAndroid Build Coastguard Worker #include <cmath>
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker #include <utility>
11*635a8641SAndroid Build Coastguard Worker
12*635a8641SAndroid Build Coastguard Worker #include "base/base_switches.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/command_line.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/debug/leak_annotations.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/location.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/memory/ref_counted_memory.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/message_loop/message_loop.h"
21*635a8641SAndroid Build Coastguard Worker #include "base/message_loop/message_loop_current.h"
22*635a8641SAndroid Build Coastguard Worker #include "base/no_destructor.h"
23*635a8641SAndroid Build Coastguard Worker #include "base/process/process_info.h"
24*635a8641SAndroid Build Coastguard Worker #include "base/process/process_metrics.h"
25*635a8641SAndroid Build Coastguard Worker #include "base/stl_util.h"
26*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
27*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
28*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_tokenizer.h"
29*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
30*635a8641SAndroid Build Coastguard Worker #include "base/sys_info.h"
31*635a8641SAndroid Build Coastguard Worker #include "base/task_scheduler/post_task.h"
32*635a8641SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
33*635a8641SAndroid Build Coastguard Worker #include "base/threading/sequenced_task_runner_handle.h"
34*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_id_name_manager.h"
35*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_task_runner_handle.h"
36*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
37*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/category_registry.h"
38*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/event_name_filter.h"
39*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/heap_profiler.h"
40*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/heap_profiler_allocation_context_tracker.h"
41*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/heap_profiler_event_filter.h"
42*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/memory_dump_manager.h"
43*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/memory_dump_provider.h"
44*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/process_memory_dump.h"
45*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/trace_buffer.h"
46*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/trace_event.h"
47*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
48*635a8641SAndroid Build Coastguard Worker
49*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
50*635a8641SAndroid Build Coastguard Worker #include "base/trace_event/trace_event_etw_export_win.h"
51*635a8641SAndroid Build Coastguard Worker #endif
52*635a8641SAndroid Build Coastguard Worker
53*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
54*635a8641SAndroid Build Coastguard Worker // The linker assigns the virtual address of the start of current library to
55*635a8641SAndroid Build Coastguard Worker // this symbol.
56*635a8641SAndroid Build Coastguard Worker extern char __executable_start;
57*635a8641SAndroid Build Coastguard Worker #endif
58*635a8641SAndroid Build Coastguard Worker
59*635a8641SAndroid Build Coastguard Worker namespace base {
60*635a8641SAndroid Build Coastguard Worker namespace trace_event {
61*635a8641SAndroid Build Coastguard Worker
62*635a8641SAndroid Build Coastguard Worker namespace {
63*635a8641SAndroid Build Coastguard Worker
64*635a8641SAndroid Build Coastguard Worker // Controls the number of trace events we will buffer in-memory
65*635a8641SAndroid Build Coastguard Worker // before throwing them away.
66*635a8641SAndroid Build Coastguard Worker const size_t kTraceBufferChunkSize = TraceBufferChunk::kTraceBufferChunkSize;
67*635a8641SAndroid Build Coastguard Worker
68*635a8641SAndroid Build Coastguard Worker const size_t kTraceEventVectorBigBufferChunks =
69*635a8641SAndroid Build Coastguard Worker 512000000 / kTraceBufferChunkSize;
70*635a8641SAndroid Build Coastguard Worker static_assert(
71*635a8641SAndroid Build Coastguard Worker kTraceEventVectorBigBufferChunks <= TraceBufferChunk::kMaxChunkIndex,
72*635a8641SAndroid Build Coastguard Worker "Too many big buffer chunks");
73*635a8641SAndroid Build Coastguard Worker const size_t kTraceEventVectorBufferChunks = 256000 / kTraceBufferChunkSize;
74*635a8641SAndroid Build Coastguard Worker static_assert(
75*635a8641SAndroid Build Coastguard Worker kTraceEventVectorBufferChunks <= TraceBufferChunk::kMaxChunkIndex,
76*635a8641SAndroid Build Coastguard Worker "Too many vector buffer chunks");
77*635a8641SAndroid Build Coastguard Worker const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4;
78*635a8641SAndroid Build Coastguard Worker
79*635a8641SAndroid Build Coastguard Worker // ECHO_TO_CONSOLE needs a small buffer to hold the unfinished COMPLETE events.
80*635a8641SAndroid Build Coastguard Worker const size_t kEchoToConsoleTraceEventBufferChunks = 256;
81*635a8641SAndroid Build Coastguard Worker
82*635a8641SAndroid Build Coastguard Worker const size_t kTraceEventBufferSizeInBytes = 100 * 1024;
83*635a8641SAndroid Build Coastguard Worker const int kThreadFlushTimeoutMs = 3000;
84*635a8641SAndroid Build Coastguard Worker
85*635a8641SAndroid Build Coastguard Worker TraceLog* g_trace_log_for_testing = nullptr;
86*635a8641SAndroid Build Coastguard Worker
87*635a8641SAndroid Build Coastguard Worker #define MAX_TRACE_EVENT_FILTERS 32
88*635a8641SAndroid Build Coastguard Worker
89*635a8641SAndroid Build Coastguard Worker // List of TraceEventFilter objects from the most recent tracing session.
GetCategoryGroupFilters()90*635a8641SAndroid Build Coastguard Worker std::vector<std::unique_ptr<TraceEventFilter>>& GetCategoryGroupFilters() {
91*635a8641SAndroid Build Coastguard Worker static auto* filters = new std::vector<std::unique_ptr<TraceEventFilter>>();
92*635a8641SAndroid Build Coastguard Worker return *filters;
93*635a8641SAndroid Build Coastguard Worker }
94*635a8641SAndroid Build Coastguard Worker
ThreadNow()95*635a8641SAndroid Build Coastguard Worker ThreadTicks ThreadNow() {
96*635a8641SAndroid Build Coastguard Worker return ThreadTicks::IsSupported()
97*635a8641SAndroid Build Coastguard Worker ? base::subtle::ThreadTicksNowIgnoringOverride()
98*635a8641SAndroid Build Coastguard Worker : ThreadTicks();
99*635a8641SAndroid Build Coastguard Worker }
100*635a8641SAndroid Build Coastguard Worker
101*635a8641SAndroid Build Coastguard Worker template <typename T>
InitializeMetadataEvent(TraceEvent * trace_event,int thread_id,const char * metadata_name,const char * arg_name,const T & value)102*635a8641SAndroid Build Coastguard Worker void InitializeMetadataEvent(TraceEvent* trace_event,
103*635a8641SAndroid Build Coastguard Worker int thread_id,
104*635a8641SAndroid Build Coastguard Worker const char* metadata_name,
105*635a8641SAndroid Build Coastguard Worker const char* arg_name,
106*635a8641SAndroid Build Coastguard Worker const T& value) {
107*635a8641SAndroid Build Coastguard Worker if (!trace_event)
108*635a8641SAndroid Build Coastguard Worker return;
109*635a8641SAndroid Build Coastguard Worker
110*635a8641SAndroid Build Coastguard Worker int num_args = 1;
111*635a8641SAndroid Build Coastguard Worker unsigned char arg_type;
112*635a8641SAndroid Build Coastguard Worker unsigned long long arg_value;
113*635a8641SAndroid Build Coastguard Worker ::trace_event_internal::SetTraceValue(value, &arg_type, &arg_value);
114*635a8641SAndroid Build Coastguard Worker trace_event->Initialize(
115*635a8641SAndroid Build Coastguard Worker thread_id,
116*635a8641SAndroid Build Coastguard Worker TimeTicks(),
117*635a8641SAndroid Build Coastguard Worker ThreadTicks(),
118*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_PHASE_METADATA,
119*635a8641SAndroid Build Coastguard Worker CategoryRegistry::kCategoryMetadata->state_ptr(),
120*635a8641SAndroid Build Coastguard Worker metadata_name,
121*635a8641SAndroid Build Coastguard Worker trace_event_internal::kGlobalScope, // scope
122*635a8641SAndroid Build Coastguard Worker trace_event_internal::kNoId, // id
123*635a8641SAndroid Build Coastguard Worker trace_event_internal::kNoId, // bind_id
124*635a8641SAndroid Build Coastguard Worker num_args,
125*635a8641SAndroid Build Coastguard Worker &arg_name,
126*635a8641SAndroid Build Coastguard Worker &arg_type,
127*635a8641SAndroid Build Coastguard Worker &arg_value,
128*635a8641SAndroid Build Coastguard Worker nullptr,
129*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_FLAG_NONE);
130*635a8641SAndroid Build Coastguard Worker }
131*635a8641SAndroid Build Coastguard Worker
132*635a8641SAndroid Build Coastguard Worker class AutoThreadLocalBoolean {
133*635a8641SAndroid Build Coastguard Worker public:
AutoThreadLocalBoolean(ThreadLocalBoolean * thread_local_boolean)134*635a8641SAndroid Build Coastguard Worker explicit AutoThreadLocalBoolean(ThreadLocalBoolean* thread_local_boolean)
135*635a8641SAndroid Build Coastguard Worker : thread_local_boolean_(thread_local_boolean) {
136*635a8641SAndroid Build Coastguard Worker DCHECK(!thread_local_boolean_->Get());
137*635a8641SAndroid Build Coastguard Worker thread_local_boolean_->Set(true);
138*635a8641SAndroid Build Coastguard Worker }
~AutoThreadLocalBoolean()139*635a8641SAndroid Build Coastguard Worker ~AutoThreadLocalBoolean() { thread_local_boolean_->Set(false); }
140*635a8641SAndroid Build Coastguard Worker
141*635a8641SAndroid Build Coastguard Worker private:
142*635a8641SAndroid Build Coastguard Worker ThreadLocalBoolean* thread_local_boolean_;
143*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(AutoThreadLocalBoolean);
144*635a8641SAndroid Build Coastguard Worker };
145*635a8641SAndroid Build Coastguard Worker
146*635a8641SAndroid Build Coastguard Worker // Use this function instead of TraceEventHandle constructor to keep the
147*635a8641SAndroid 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)148*635a8641SAndroid Build Coastguard Worker void MakeHandle(uint32_t chunk_seq,
149*635a8641SAndroid Build Coastguard Worker size_t chunk_index,
150*635a8641SAndroid Build Coastguard Worker size_t event_index,
151*635a8641SAndroid Build Coastguard Worker TraceEventHandle* handle) {
152*635a8641SAndroid Build Coastguard Worker DCHECK(chunk_seq);
153*635a8641SAndroid Build Coastguard Worker DCHECK(chunk_index <= TraceBufferChunk::kMaxChunkIndex);
154*635a8641SAndroid Build Coastguard Worker DCHECK(event_index < TraceBufferChunk::kTraceBufferChunkSize);
155*635a8641SAndroid Build Coastguard Worker DCHECK(chunk_index <= std::numeric_limits<uint16_t>::max());
156*635a8641SAndroid Build Coastguard Worker handle->chunk_seq = chunk_seq;
157*635a8641SAndroid Build Coastguard Worker handle->chunk_index = static_cast<uint16_t>(chunk_index);
158*635a8641SAndroid Build Coastguard Worker handle->event_index = static_cast<uint16_t>(event_index);
159*635a8641SAndroid Build Coastguard Worker }
160*635a8641SAndroid Build Coastguard Worker
161*635a8641SAndroid Build Coastguard Worker template <typename Function>
ForEachCategoryFilter(const unsigned char * category_group_enabled,Function filter_fn)162*635a8641SAndroid Build Coastguard Worker void ForEachCategoryFilter(const unsigned char* category_group_enabled,
163*635a8641SAndroid Build Coastguard Worker Function filter_fn) {
164*635a8641SAndroid Build Coastguard Worker const TraceCategory* category =
165*635a8641SAndroid Build Coastguard Worker CategoryRegistry::GetCategoryByStatePtr(category_group_enabled);
166*635a8641SAndroid Build Coastguard Worker uint32_t filter_bitmap = category->enabled_filters();
167*635a8641SAndroid Build Coastguard Worker for (int index = 0; filter_bitmap != 0; filter_bitmap >>= 1, index++) {
168*635a8641SAndroid Build Coastguard Worker if (filter_bitmap & 1 && GetCategoryGroupFilters()[index])
169*635a8641SAndroid Build Coastguard Worker filter_fn(GetCategoryGroupFilters()[index].get());
170*635a8641SAndroid Build Coastguard Worker }
171*635a8641SAndroid Build Coastguard Worker }
172*635a8641SAndroid Build Coastguard Worker
173*635a8641SAndroid Build Coastguard Worker } // namespace
174*635a8641SAndroid Build Coastguard Worker
175*635a8641SAndroid Build Coastguard Worker // A helper class that allows the lock to be acquired in the middle of the scope
176*635a8641SAndroid Build Coastguard Worker // and unlocks at the end of scope if locked.
177*635a8641SAndroid Build Coastguard Worker class TraceLog::OptionalAutoLock {
178*635a8641SAndroid Build Coastguard Worker public:
OptionalAutoLock(Lock * lock)179*635a8641SAndroid Build Coastguard Worker explicit OptionalAutoLock(Lock* lock) : lock_(lock), locked_(false) {}
180*635a8641SAndroid Build Coastguard Worker
~OptionalAutoLock()181*635a8641SAndroid Build Coastguard Worker ~OptionalAutoLock() {
182*635a8641SAndroid Build Coastguard Worker if (locked_)
183*635a8641SAndroid Build Coastguard Worker lock_->Release();
184*635a8641SAndroid Build Coastguard Worker }
185*635a8641SAndroid Build Coastguard Worker
EnsureAcquired()186*635a8641SAndroid Build Coastguard Worker void EnsureAcquired() {
187*635a8641SAndroid Build Coastguard Worker if (!locked_) {
188*635a8641SAndroid Build Coastguard Worker lock_->Acquire();
189*635a8641SAndroid Build Coastguard Worker locked_ = true;
190*635a8641SAndroid Build Coastguard Worker }
191*635a8641SAndroid Build Coastguard Worker }
192*635a8641SAndroid Build Coastguard Worker
193*635a8641SAndroid Build Coastguard Worker private:
194*635a8641SAndroid Build Coastguard Worker Lock* lock_;
195*635a8641SAndroid Build Coastguard Worker bool locked_;
196*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(OptionalAutoLock);
197*635a8641SAndroid Build Coastguard Worker };
198*635a8641SAndroid Build Coastguard Worker
199*635a8641SAndroid Build Coastguard Worker class TraceLog::ThreadLocalEventBuffer
200*635a8641SAndroid Build Coastguard Worker : public MessageLoopCurrent::DestructionObserver,
201*635a8641SAndroid Build Coastguard Worker public MemoryDumpProvider {
202*635a8641SAndroid Build Coastguard Worker public:
203*635a8641SAndroid Build Coastguard Worker explicit ThreadLocalEventBuffer(TraceLog* trace_log);
204*635a8641SAndroid Build Coastguard Worker ~ThreadLocalEventBuffer() override;
205*635a8641SAndroid Build Coastguard Worker
206*635a8641SAndroid Build Coastguard Worker TraceEvent* AddTraceEvent(TraceEventHandle* handle);
207*635a8641SAndroid Build Coastguard Worker
GetEventByHandle(TraceEventHandle handle)208*635a8641SAndroid Build Coastguard Worker TraceEvent* GetEventByHandle(TraceEventHandle handle) {
209*635a8641SAndroid Build Coastguard Worker if (!chunk_ || handle.chunk_seq != chunk_->seq() ||
210*635a8641SAndroid Build Coastguard Worker handle.chunk_index != chunk_index_) {
211*635a8641SAndroid Build Coastguard Worker return nullptr;
212*635a8641SAndroid Build Coastguard Worker }
213*635a8641SAndroid Build Coastguard Worker
214*635a8641SAndroid Build Coastguard Worker return chunk_->GetEventAt(handle.event_index);
215*635a8641SAndroid Build Coastguard Worker }
216*635a8641SAndroid Build Coastguard Worker
generation() const217*635a8641SAndroid Build Coastguard Worker int generation() const { return generation_; }
218*635a8641SAndroid Build Coastguard Worker
219*635a8641SAndroid Build Coastguard Worker private:
220*635a8641SAndroid Build Coastguard Worker // MessageLoopCurrent::DestructionObserver
221*635a8641SAndroid Build Coastguard Worker void WillDestroyCurrentMessageLoop() override;
222*635a8641SAndroid Build Coastguard Worker
223*635a8641SAndroid Build Coastguard Worker // MemoryDumpProvider implementation.
224*635a8641SAndroid Build Coastguard Worker bool OnMemoryDump(const MemoryDumpArgs& args,
225*635a8641SAndroid Build Coastguard Worker ProcessMemoryDump* pmd) override;
226*635a8641SAndroid Build Coastguard Worker
227*635a8641SAndroid Build Coastguard Worker void FlushWhileLocked();
228*635a8641SAndroid Build Coastguard Worker
CheckThisIsCurrentBuffer() const229*635a8641SAndroid Build Coastguard Worker void CheckThisIsCurrentBuffer() const {
230*635a8641SAndroid Build Coastguard Worker DCHECK(trace_log_->thread_local_event_buffer_.Get() == this);
231*635a8641SAndroid Build Coastguard Worker }
232*635a8641SAndroid Build Coastguard Worker
233*635a8641SAndroid Build Coastguard Worker // Since TraceLog is a leaky singleton, trace_log_ will always be valid
234*635a8641SAndroid Build Coastguard Worker // as long as the thread exists.
235*635a8641SAndroid Build Coastguard Worker TraceLog* trace_log_;
236*635a8641SAndroid Build Coastguard Worker std::unique_ptr<TraceBufferChunk> chunk_;
237*635a8641SAndroid Build Coastguard Worker size_t chunk_index_;
238*635a8641SAndroid Build Coastguard Worker int generation_;
239*635a8641SAndroid Build Coastguard Worker
240*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ThreadLocalEventBuffer);
241*635a8641SAndroid Build Coastguard Worker };
242*635a8641SAndroid Build Coastguard Worker
ThreadLocalEventBuffer(TraceLog * trace_log)243*635a8641SAndroid Build Coastguard Worker TraceLog::ThreadLocalEventBuffer::ThreadLocalEventBuffer(TraceLog* trace_log)
244*635a8641SAndroid Build Coastguard Worker : trace_log_(trace_log),
245*635a8641SAndroid Build Coastguard Worker chunk_index_(0),
246*635a8641SAndroid Build Coastguard Worker generation_(trace_log->generation()) {
247*635a8641SAndroid Build Coastguard Worker // ThreadLocalEventBuffer is created only if the thread has a message loop, so
248*635a8641SAndroid Build Coastguard Worker // the following message_loop won't be NULL.
249*635a8641SAndroid Build Coastguard Worker MessageLoop* message_loop = MessageLoop::current();
250*635a8641SAndroid Build Coastguard Worker message_loop->AddDestructionObserver(this);
251*635a8641SAndroid Build Coastguard Worker
252*635a8641SAndroid Build Coastguard Worker // This is to report the local memory usage when memory-infra is enabled.
253*635a8641SAndroid Build Coastguard Worker MemoryDumpManager::GetInstance()->RegisterDumpProvider(
254*635a8641SAndroid Build Coastguard Worker this, "ThreadLocalEventBuffer", ThreadTaskRunnerHandle::Get());
255*635a8641SAndroid Build Coastguard Worker
256*635a8641SAndroid Build Coastguard Worker AutoLock lock(trace_log->lock_);
257*635a8641SAndroid Build Coastguard Worker trace_log->thread_message_loops_.insert(message_loop);
258*635a8641SAndroid Build Coastguard Worker }
259*635a8641SAndroid Build Coastguard Worker
~ThreadLocalEventBuffer()260*635a8641SAndroid Build Coastguard Worker TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() {
261*635a8641SAndroid Build Coastguard Worker CheckThisIsCurrentBuffer();
262*635a8641SAndroid Build Coastguard Worker MessageLoop::current()->RemoveDestructionObserver(this);
263*635a8641SAndroid Build Coastguard Worker MemoryDumpManager::GetInstance()->UnregisterDumpProvider(this);
264*635a8641SAndroid Build Coastguard Worker
265*635a8641SAndroid Build Coastguard Worker {
266*635a8641SAndroid Build Coastguard Worker AutoLock lock(trace_log_->lock_);
267*635a8641SAndroid Build Coastguard Worker FlushWhileLocked();
268*635a8641SAndroid Build Coastguard Worker trace_log_->thread_message_loops_.erase(MessageLoop::current());
269*635a8641SAndroid Build Coastguard Worker }
270*635a8641SAndroid Build Coastguard Worker trace_log_->thread_local_event_buffer_.Set(nullptr);
271*635a8641SAndroid Build Coastguard Worker }
272*635a8641SAndroid Build Coastguard Worker
AddTraceEvent(TraceEventHandle * handle)273*635a8641SAndroid Build Coastguard Worker TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent(
274*635a8641SAndroid Build Coastguard Worker TraceEventHandle* handle) {
275*635a8641SAndroid Build Coastguard Worker CheckThisIsCurrentBuffer();
276*635a8641SAndroid Build Coastguard Worker
277*635a8641SAndroid Build Coastguard Worker if (chunk_ && chunk_->IsFull()) {
278*635a8641SAndroid Build Coastguard Worker AutoLock lock(trace_log_->lock_);
279*635a8641SAndroid Build Coastguard Worker FlushWhileLocked();
280*635a8641SAndroid Build Coastguard Worker chunk_.reset();
281*635a8641SAndroid Build Coastguard Worker }
282*635a8641SAndroid Build Coastguard Worker if (!chunk_) {
283*635a8641SAndroid Build Coastguard Worker AutoLock lock(trace_log_->lock_);
284*635a8641SAndroid Build Coastguard Worker chunk_ = trace_log_->logged_events_->GetChunk(&chunk_index_);
285*635a8641SAndroid Build Coastguard Worker trace_log_->CheckIfBufferIsFullWhileLocked();
286*635a8641SAndroid Build Coastguard Worker }
287*635a8641SAndroid Build Coastguard Worker if (!chunk_)
288*635a8641SAndroid Build Coastguard Worker return nullptr;
289*635a8641SAndroid Build Coastguard Worker
290*635a8641SAndroid Build Coastguard Worker size_t event_index;
291*635a8641SAndroid Build Coastguard Worker TraceEvent* trace_event = chunk_->AddTraceEvent(&event_index);
292*635a8641SAndroid Build Coastguard Worker if (trace_event && handle)
293*635a8641SAndroid Build Coastguard Worker MakeHandle(chunk_->seq(), chunk_index_, event_index, handle);
294*635a8641SAndroid Build Coastguard Worker
295*635a8641SAndroid Build Coastguard Worker return trace_event;
296*635a8641SAndroid Build Coastguard Worker }
297*635a8641SAndroid Build Coastguard Worker
WillDestroyCurrentMessageLoop()298*635a8641SAndroid Build Coastguard Worker void TraceLog::ThreadLocalEventBuffer::WillDestroyCurrentMessageLoop() {
299*635a8641SAndroid Build Coastguard Worker delete this;
300*635a8641SAndroid Build Coastguard Worker }
301*635a8641SAndroid Build Coastguard Worker
OnMemoryDump(const MemoryDumpArgs & args,ProcessMemoryDump * pmd)302*635a8641SAndroid Build Coastguard Worker bool TraceLog::ThreadLocalEventBuffer::OnMemoryDump(const MemoryDumpArgs& args,
303*635a8641SAndroid Build Coastguard Worker ProcessMemoryDump* pmd) {
304*635a8641SAndroid Build Coastguard Worker if (!chunk_)
305*635a8641SAndroid Build Coastguard Worker return true;
306*635a8641SAndroid Build Coastguard Worker std::string dump_base_name = StringPrintf(
307*635a8641SAndroid Build Coastguard Worker "tracing/thread_%d", static_cast<int>(PlatformThread::CurrentId()));
308*635a8641SAndroid Build Coastguard Worker TraceEventMemoryOverhead overhead;
309*635a8641SAndroid Build Coastguard Worker chunk_->EstimateTraceMemoryOverhead(&overhead);
310*635a8641SAndroid Build Coastguard Worker overhead.DumpInto(dump_base_name.c_str(), pmd);
311*635a8641SAndroid Build Coastguard Worker return true;
312*635a8641SAndroid Build Coastguard Worker }
313*635a8641SAndroid Build Coastguard Worker
FlushWhileLocked()314*635a8641SAndroid Build Coastguard Worker void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() {
315*635a8641SAndroid Build Coastguard Worker if (!chunk_)
316*635a8641SAndroid Build Coastguard Worker return;
317*635a8641SAndroid Build Coastguard Worker
318*635a8641SAndroid Build Coastguard Worker trace_log_->lock_.AssertAcquired();
319*635a8641SAndroid Build Coastguard Worker if (trace_log_->CheckGeneration(generation_)) {
320*635a8641SAndroid Build Coastguard Worker // Return the chunk to the buffer only if the generation matches.
321*635a8641SAndroid Build Coastguard Worker trace_log_->logged_events_->ReturnChunk(chunk_index_, std::move(chunk_));
322*635a8641SAndroid Build Coastguard Worker }
323*635a8641SAndroid Build Coastguard Worker // Otherwise this method may be called from the destructor, or TraceLog will
324*635a8641SAndroid Build Coastguard Worker // find the generation mismatch and delete this buffer soon.
325*635a8641SAndroid Build Coastguard Worker }
326*635a8641SAndroid Build Coastguard Worker
SetAddTraceEventOverride(const AddTraceEventOverrideCallback & override)327*635a8641SAndroid Build Coastguard Worker void TraceLog::SetAddTraceEventOverride(
328*635a8641SAndroid Build Coastguard Worker const AddTraceEventOverrideCallback& override) {
329*635a8641SAndroid Build Coastguard Worker subtle::NoBarrier_Store(&trace_event_override_,
330*635a8641SAndroid Build Coastguard Worker reinterpret_cast<subtle::AtomicWord>(override));
331*635a8641SAndroid Build Coastguard Worker }
332*635a8641SAndroid Build Coastguard Worker
333*635a8641SAndroid Build Coastguard Worker struct TraceLog::RegisteredAsyncObserver {
RegisteredAsyncObserverbase::trace_event::TraceLog::RegisteredAsyncObserver334*635a8641SAndroid Build Coastguard Worker explicit RegisteredAsyncObserver(WeakPtr<AsyncEnabledStateObserver> observer)
335*635a8641SAndroid Build Coastguard Worker : observer(observer), task_runner(ThreadTaskRunnerHandle::Get()) {}
336*635a8641SAndroid Build Coastguard Worker ~RegisteredAsyncObserver() = default;
337*635a8641SAndroid Build Coastguard Worker
338*635a8641SAndroid Build Coastguard Worker WeakPtr<AsyncEnabledStateObserver> observer;
339*635a8641SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> task_runner;
340*635a8641SAndroid Build Coastguard Worker };
341*635a8641SAndroid Build Coastguard Worker
TraceLogStatus()342*635a8641SAndroid Build Coastguard Worker TraceLogStatus::TraceLogStatus() : event_capacity(0), event_count(0) {}
343*635a8641SAndroid Build Coastguard Worker
344*635a8641SAndroid Build Coastguard Worker TraceLogStatus::~TraceLogStatus() = default;
345*635a8641SAndroid Build Coastguard Worker
346*635a8641SAndroid Build Coastguard Worker // static
GetInstance()347*635a8641SAndroid Build Coastguard Worker TraceLog* TraceLog::GetInstance() {
348*635a8641SAndroid Build Coastguard Worker static base::NoDestructor<TraceLog> instance;
349*635a8641SAndroid Build Coastguard Worker return instance.get();
350*635a8641SAndroid Build Coastguard Worker }
351*635a8641SAndroid Build Coastguard Worker
352*635a8641SAndroid Build Coastguard Worker // static
ResetForTesting()353*635a8641SAndroid Build Coastguard Worker void TraceLog::ResetForTesting() {
354*635a8641SAndroid Build Coastguard Worker if (!g_trace_log_for_testing)
355*635a8641SAndroid Build Coastguard Worker return;
356*635a8641SAndroid Build Coastguard Worker CategoryRegistry::ResetForTesting();
357*635a8641SAndroid Build Coastguard Worker g_trace_log_for_testing->~TraceLog();
358*635a8641SAndroid Build Coastguard Worker new (g_trace_log_for_testing) TraceLog;
359*635a8641SAndroid Build Coastguard Worker }
360*635a8641SAndroid Build Coastguard Worker
TraceLog()361*635a8641SAndroid Build Coastguard Worker TraceLog::TraceLog()
362*635a8641SAndroid Build Coastguard Worker : enabled_modes_(0),
363*635a8641SAndroid Build Coastguard Worker num_traces_recorded_(0),
364*635a8641SAndroid Build Coastguard Worker dispatching_to_observer_list_(false),
365*635a8641SAndroid Build Coastguard Worker process_sort_index_(0),
366*635a8641SAndroid Build Coastguard Worker process_id_hash_(0),
367*635a8641SAndroid Build Coastguard Worker process_id_(0),
368*635a8641SAndroid Build Coastguard Worker trace_options_(kInternalRecordUntilFull),
369*635a8641SAndroid Build Coastguard Worker trace_config_(TraceConfig()),
370*635a8641SAndroid Build Coastguard Worker thread_shared_chunk_index_(0),
371*635a8641SAndroid Build Coastguard Worker generation_(0),
372*635a8641SAndroid Build Coastguard Worker use_worker_thread_(false),
373*635a8641SAndroid Build Coastguard Worker trace_event_override_(0),
374*635a8641SAndroid Build Coastguard Worker filter_factory_for_testing_(nullptr) {
375*635a8641SAndroid Build Coastguard Worker CategoryRegistry::Initialize();
376*635a8641SAndroid Build Coastguard Worker
377*635a8641SAndroid Build Coastguard Worker #if defined(OS_NACL) // NaCl shouldn't expose the process id.
378*635a8641SAndroid Build Coastguard Worker SetProcessID(0);
379*635a8641SAndroid Build Coastguard Worker #else
380*635a8641SAndroid Build Coastguard Worker SetProcessID(static_cast<int>(GetCurrentProcId()));
381*635a8641SAndroid Build Coastguard Worker #endif
382*635a8641SAndroid Build Coastguard Worker
383*635a8641SAndroid Build Coastguard Worker // Linux renderer processes and Android O processes are not allowed to read
384*635a8641SAndroid Build Coastguard Worker // "proc/stat" file, crbug.com/788870.
385*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
386*635a8641SAndroid Build Coastguard Worker process_creation_time_ = CurrentProcessInfo::CreationTime();
387*635a8641SAndroid Build Coastguard Worker #else
388*635a8641SAndroid Build Coastguard Worker // Use approximate time when creation time is not available.
389*635a8641SAndroid Build Coastguard Worker process_creation_time_ = TRACE_TIME_NOW();
390*635a8641SAndroid Build Coastguard Worker #endif
391*635a8641SAndroid Build Coastguard Worker
392*635a8641SAndroid Build Coastguard Worker logged_events_.reset(CreateTraceBuffer());
393*635a8641SAndroid Build Coastguard Worker
394*635a8641SAndroid Build Coastguard Worker MemoryDumpManager::GetInstance()->RegisterDumpProvider(this, "TraceLog",
395*635a8641SAndroid Build Coastguard Worker nullptr);
396*635a8641SAndroid Build Coastguard Worker g_trace_log_for_testing = this;
397*635a8641SAndroid Build Coastguard Worker }
398*635a8641SAndroid Build Coastguard Worker
399*635a8641SAndroid Build Coastguard Worker TraceLog::~TraceLog() = default;
400*635a8641SAndroid Build Coastguard Worker
InitializeThreadLocalEventBufferIfSupported()401*635a8641SAndroid Build Coastguard Worker void TraceLog::InitializeThreadLocalEventBufferIfSupported() {
402*635a8641SAndroid Build Coastguard Worker // A ThreadLocalEventBuffer needs the message loop
403*635a8641SAndroid Build Coastguard Worker // - to know when the thread exits;
404*635a8641SAndroid Build Coastguard Worker // - to handle the final flush.
405*635a8641SAndroid Build Coastguard Worker // For a thread without a message loop or the message loop may be blocked, the
406*635a8641SAndroid Build Coastguard Worker // trace events will be added into the main buffer directly.
407*635a8641SAndroid Build Coastguard Worker if (thread_blocks_message_loop_.Get() || !MessageLoopCurrent::IsSet())
408*635a8641SAndroid Build Coastguard Worker return;
409*635a8641SAndroid Build Coastguard Worker HEAP_PROFILER_SCOPED_IGNORE;
410*635a8641SAndroid Build Coastguard Worker auto* thread_local_event_buffer = thread_local_event_buffer_.Get();
411*635a8641SAndroid Build Coastguard Worker if (thread_local_event_buffer &&
412*635a8641SAndroid Build Coastguard Worker !CheckGeneration(thread_local_event_buffer->generation())) {
413*635a8641SAndroid Build Coastguard Worker delete thread_local_event_buffer;
414*635a8641SAndroid Build Coastguard Worker thread_local_event_buffer = nullptr;
415*635a8641SAndroid Build Coastguard Worker }
416*635a8641SAndroid Build Coastguard Worker if (!thread_local_event_buffer) {
417*635a8641SAndroid Build Coastguard Worker thread_local_event_buffer = new ThreadLocalEventBuffer(this);
418*635a8641SAndroid Build Coastguard Worker thread_local_event_buffer_.Set(thread_local_event_buffer);
419*635a8641SAndroid Build Coastguard Worker }
420*635a8641SAndroid Build Coastguard Worker }
421*635a8641SAndroid Build Coastguard Worker
OnMemoryDump(const MemoryDumpArgs & args,ProcessMemoryDump * pmd)422*635a8641SAndroid Build Coastguard Worker bool TraceLog::OnMemoryDump(const MemoryDumpArgs& args,
423*635a8641SAndroid Build Coastguard Worker ProcessMemoryDump* pmd) {
424*635a8641SAndroid Build Coastguard Worker // TODO(ssid): Use MemoryDumpArgs to create light dumps when requested
425*635a8641SAndroid Build Coastguard Worker // (crbug.com/499731).
426*635a8641SAndroid Build Coastguard Worker TraceEventMemoryOverhead overhead;
427*635a8641SAndroid Build Coastguard Worker overhead.Add(TraceEventMemoryOverhead::kOther, sizeof(*this));
428*635a8641SAndroid Build Coastguard Worker {
429*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
430*635a8641SAndroid Build Coastguard Worker if (logged_events_)
431*635a8641SAndroid Build Coastguard Worker logged_events_->EstimateTraceMemoryOverhead(&overhead);
432*635a8641SAndroid Build Coastguard Worker
433*635a8641SAndroid Build Coastguard Worker for (auto& metadata_event : metadata_events_)
434*635a8641SAndroid Build Coastguard Worker metadata_event->EstimateTraceMemoryOverhead(&overhead);
435*635a8641SAndroid Build Coastguard Worker }
436*635a8641SAndroid Build Coastguard Worker overhead.AddSelf();
437*635a8641SAndroid Build Coastguard Worker overhead.DumpInto("tracing/main_trace_log", pmd);
438*635a8641SAndroid Build Coastguard Worker return true;
439*635a8641SAndroid Build Coastguard Worker }
440*635a8641SAndroid Build Coastguard Worker
GetCategoryGroupEnabled(const char * category_group)441*635a8641SAndroid Build Coastguard Worker const unsigned char* TraceLog::GetCategoryGroupEnabled(
442*635a8641SAndroid Build Coastguard Worker const char* category_group) {
443*635a8641SAndroid Build Coastguard Worker TraceLog* tracelog = GetInstance();
444*635a8641SAndroid Build Coastguard Worker if (!tracelog) {
445*635a8641SAndroid Build Coastguard Worker DCHECK(!CategoryRegistry::kCategoryAlreadyShutdown->is_enabled());
446*635a8641SAndroid Build Coastguard Worker return CategoryRegistry::kCategoryAlreadyShutdown->state_ptr();
447*635a8641SAndroid Build Coastguard Worker }
448*635a8641SAndroid Build Coastguard Worker TraceCategory* category = CategoryRegistry::GetCategoryByName(category_group);
449*635a8641SAndroid Build Coastguard Worker if (!category) {
450*635a8641SAndroid Build Coastguard Worker // Slow path: in the case of a new category we have to repeat the check
451*635a8641SAndroid Build Coastguard Worker // holding the lock, as multiple threads might have reached this point
452*635a8641SAndroid Build Coastguard Worker // at the same time.
453*635a8641SAndroid Build Coastguard Worker auto category_initializer = [](TraceCategory* category) {
454*635a8641SAndroid Build Coastguard Worker TraceLog::GetInstance()->UpdateCategoryState(category);
455*635a8641SAndroid Build Coastguard Worker };
456*635a8641SAndroid Build Coastguard Worker AutoLock lock(tracelog->lock_);
457*635a8641SAndroid Build Coastguard Worker CategoryRegistry::GetOrCreateCategoryLocked(
458*635a8641SAndroid Build Coastguard Worker category_group, category_initializer, &category);
459*635a8641SAndroid Build Coastguard Worker }
460*635a8641SAndroid Build Coastguard Worker DCHECK(category->state_ptr());
461*635a8641SAndroid Build Coastguard Worker return category->state_ptr();
462*635a8641SAndroid Build Coastguard Worker }
463*635a8641SAndroid Build Coastguard Worker
GetCategoryGroupName(const unsigned char * category_group_enabled)464*635a8641SAndroid Build Coastguard Worker const char* TraceLog::GetCategoryGroupName(
465*635a8641SAndroid Build Coastguard Worker const unsigned char* category_group_enabled) {
466*635a8641SAndroid Build Coastguard Worker return CategoryRegistry::GetCategoryByStatePtr(category_group_enabled)
467*635a8641SAndroid Build Coastguard Worker ->name();
468*635a8641SAndroid Build Coastguard Worker }
469*635a8641SAndroid Build Coastguard Worker
UpdateCategoryState(TraceCategory * category)470*635a8641SAndroid Build Coastguard Worker void TraceLog::UpdateCategoryState(TraceCategory* category) {
471*635a8641SAndroid Build Coastguard Worker lock_.AssertAcquired();
472*635a8641SAndroid Build Coastguard Worker DCHECK(category->is_valid());
473*635a8641SAndroid Build Coastguard Worker unsigned char state_flags = 0;
474*635a8641SAndroid Build Coastguard Worker if (enabled_modes_ & RECORDING_MODE &&
475*635a8641SAndroid Build Coastguard Worker trace_config_.IsCategoryGroupEnabled(category->name())) {
476*635a8641SAndroid Build Coastguard Worker state_flags |= TraceCategory::ENABLED_FOR_RECORDING;
477*635a8641SAndroid Build Coastguard Worker }
478*635a8641SAndroid Build Coastguard Worker
479*635a8641SAndroid Build Coastguard Worker // TODO(primiano): this is a temporary workaround for catapult:#2341,
480*635a8641SAndroid Build Coastguard Worker // to guarantee that metadata events are always added even if the category
481*635a8641SAndroid Build Coastguard Worker // filter is "-*". See crbug.com/618054 for more details and long-term fix.
482*635a8641SAndroid Build Coastguard Worker if (enabled_modes_ & RECORDING_MODE &&
483*635a8641SAndroid Build Coastguard Worker category == CategoryRegistry::kCategoryMetadata) {
484*635a8641SAndroid Build Coastguard Worker state_flags |= TraceCategory::ENABLED_FOR_RECORDING;
485*635a8641SAndroid Build Coastguard Worker }
486*635a8641SAndroid Build Coastguard Worker
487*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
488*635a8641SAndroid Build Coastguard Worker if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled(
489*635a8641SAndroid Build Coastguard Worker category->name())) {
490*635a8641SAndroid Build Coastguard Worker state_flags |= TraceCategory::ENABLED_FOR_ETW_EXPORT;
491*635a8641SAndroid Build Coastguard Worker }
492*635a8641SAndroid Build Coastguard Worker #endif
493*635a8641SAndroid Build Coastguard Worker
494*635a8641SAndroid Build Coastguard Worker uint32_t enabled_filters_bitmap = 0;
495*635a8641SAndroid Build Coastguard Worker int index = 0;
496*635a8641SAndroid Build Coastguard Worker for (const auto& event_filter : enabled_event_filters_) {
497*635a8641SAndroid Build Coastguard Worker if (event_filter.IsCategoryGroupEnabled(category->name())) {
498*635a8641SAndroid Build Coastguard Worker state_flags |= TraceCategory::ENABLED_FOR_FILTERING;
499*635a8641SAndroid Build Coastguard Worker DCHECK(GetCategoryGroupFilters()[index]);
500*635a8641SAndroid Build Coastguard Worker enabled_filters_bitmap |= 1 << index;
501*635a8641SAndroid Build Coastguard Worker }
502*635a8641SAndroid Build Coastguard Worker if (index++ >= MAX_TRACE_EVENT_FILTERS) {
503*635a8641SAndroid Build Coastguard Worker NOTREACHED();
504*635a8641SAndroid Build Coastguard Worker break;
505*635a8641SAndroid Build Coastguard Worker }
506*635a8641SAndroid Build Coastguard Worker }
507*635a8641SAndroid Build Coastguard Worker category->set_enabled_filters(enabled_filters_bitmap);
508*635a8641SAndroid Build Coastguard Worker category->set_state(state_flags);
509*635a8641SAndroid Build Coastguard Worker }
510*635a8641SAndroid Build Coastguard Worker
UpdateCategoryRegistry()511*635a8641SAndroid Build Coastguard Worker void TraceLog::UpdateCategoryRegistry() {
512*635a8641SAndroid Build Coastguard Worker lock_.AssertAcquired();
513*635a8641SAndroid Build Coastguard Worker CreateFiltersForTraceConfig();
514*635a8641SAndroid Build Coastguard Worker for (TraceCategory& category : CategoryRegistry::GetAllCategories()) {
515*635a8641SAndroid Build Coastguard Worker UpdateCategoryState(&category);
516*635a8641SAndroid Build Coastguard Worker }
517*635a8641SAndroid Build Coastguard Worker }
518*635a8641SAndroid Build Coastguard Worker
CreateFiltersForTraceConfig()519*635a8641SAndroid Build Coastguard Worker void TraceLog::CreateFiltersForTraceConfig() {
520*635a8641SAndroid Build Coastguard Worker if (!(enabled_modes_ & FILTERING_MODE))
521*635a8641SAndroid Build Coastguard Worker return;
522*635a8641SAndroid Build Coastguard Worker
523*635a8641SAndroid Build Coastguard Worker // Filters were already added and tracing could be enabled. Filters list
524*635a8641SAndroid Build Coastguard Worker // cannot be changed when trace events are using them.
525*635a8641SAndroid Build Coastguard Worker if (GetCategoryGroupFilters().size())
526*635a8641SAndroid Build Coastguard Worker return;
527*635a8641SAndroid Build Coastguard Worker
528*635a8641SAndroid Build Coastguard Worker for (auto& filter_config : enabled_event_filters_) {
529*635a8641SAndroid Build Coastguard Worker if (GetCategoryGroupFilters().size() >= MAX_TRACE_EVENT_FILTERS) {
530*635a8641SAndroid Build Coastguard Worker NOTREACHED()
531*635a8641SAndroid Build Coastguard Worker << "Too many trace event filters installed in the current session";
532*635a8641SAndroid Build Coastguard Worker break;
533*635a8641SAndroid Build Coastguard Worker }
534*635a8641SAndroid Build Coastguard Worker
535*635a8641SAndroid Build Coastguard Worker std::unique_ptr<TraceEventFilter> new_filter;
536*635a8641SAndroid Build Coastguard Worker const std::string& predicate_name = filter_config.predicate_name();
537*635a8641SAndroid Build Coastguard Worker if (predicate_name == EventNameFilter::kName) {
538*635a8641SAndroid Build Coastguard Worker auto whitelist = std::make_unique<std::unordered_set<std::string>>();
539*635a8641SAndroid Build Coastguard Worker CHECK(filter_config.GetArgAsSet("event_name_whitelist", &*whitelist));
540*635a8641SAndroid Build Coastguard Worker new_filter = std::make_unique<EventNameFilter>(std::move(whitelist));
541*635a8641SAndroid Build Coastguard Worker } else if (predicate_name == HeapProfilerEventFilter::kName) {
542*635a8641SAndroid Build Coastguard Worker new_filter = std::make_unique<HeapProfilerEventFilter>();
543*635a8641SAndroid Build Coastguard Worker } else {
544*635a8641SAndroid Build Coastguard Worker if (filter_factory_for_testing_)
545*635a8641SAndroid Build Coastguard Worker new_filter = filter_factory_for_testing_(predicate_name);
546*635a8641SAndroid Build Coastguard Worker CHECK(new_filter) << "Unknown trace filter " << predicate_name;
547*635a8641SAndroid Build Coastguard Worker }
548*635a8641SAndroid Build Coastguard Worker GetCategoryGroupFilters().push_back(std::move(new_filter));
549*635a8641SAndroid Build Coastguard Worker }
550*635a8641SAndroid Build Coastguard Worker }
551*635a8641SAndroid Build Coastguard Worker
GetKnownCategoryGroups(std::vector<std::string> * category_groups)552*635a8641SAndroid Build Coastguard Worker void TraceLog::GetKnownCategoryGroups(
553*635a8641SAndroid Build Coastguard Worker std::vector<std::string>* category_groups) {
554*635a8641SAndroid Build Coastguard Worker for (const auto& category : CategoryRegistry::GetAllCategories()) {
555*635a8641SAndroid Build Coastguard Worker if (!CategoryRegistry::IsBuiltinCategory(&category))
556*635a8641SAndroid Build Coastguard Worker category_groups->push_back(category.name());
557*635a8641SAndroid Build Coastguard Worker }
558*635a8641SAndroid Build Coastguard Worker }
559*635a8641SAndroid Build Coastguard Worker
SetEnabled(const TraceConfig & trace_config,uint8_t modes_to_enable)560*635a8641SAndroid Build Coastguard Worker void TraceLog::SetEnabled(const TraceConfig& trace_config,
561*635a8641SAndroid Build Coastguard Worker uint8_t modes_to_enable) {
562*635a8641SAndroid Build Coastguard Worker DCHECK(trace_config.process_filter_config().IsEnabled(process_id_));
563*635a8641SAndroid Build Coastguard Worker
564*635a8641SAndroid Build Coastguard Worker std::vector<EnabledStateObserver*> observer_list;
565*635a8641SAndroid Build Coastguard Worker std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> observer_map;
566*635a8641SAndroid Build Coastguard Worker {
567*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
568*635a8641SAndroid Build Coastguard Worker
569*635a8641SAndroid Build Coastguard Worker // Can't enable tracing when Flush() is in progress.
570*635a8641SAndroid Build Coastguard Worker DCHECK(!flush_task_runner_);
571*635a8641SAndroid Build Coastguard Worker
572*635a8641SAndroid Build Coastguard Worker InternalTraceOptions new_options =
573*635a8641SAndroid Build Coastguard Worker GetInternalOptionsFromTraceConfig(trace_config);
574*635a8641SAndroid Build Coastguard Worker
575*635a8641SAndroid Build Coastguard Worker InternalTraceOptions old_options = trace_options();
576*635a8641SAndroid Build Coastguard Worker
577*635a8641SAndroid Build Coastguard Worker if (dispatching_to_observer_list_) {
578*635a8641SAndroid Build Coastguard Worker // TODO(ssid): Change to NOTREACHED after fixing crbug.com/625170.
579*635a8641SAndroid Build Coastguard Worker DLOG(ERROR)
580*635a8641SAndroid Build Coastguard Worker << "Cannot manipulate TraceLog::Enabled state from an observer.";
581*635a8641SAndroid Build Coastguard Worker return;
582*635a8641SAndroid Build Coastguard Worker }
583*635a8641SAndroid Build Coastguard Worker
584*635a8641SAndroid Build Coastguard Worker // Clear all filters from previous tracing session. These filters are not
585*635a8641SAndroid Build Coastguard Worker // cleared at the end of tracing because some threads which hit trace event
586*635a8641SAndroid Build Coastguard Worker // when disabling, could try to use the filters.
587*635a8641SAndroid Build Coastguard Worker if (!enabled_modes_)
588*635a8641SAndroid Build Coastguard Worker GetCategoryGroupFilters().clear();
589*635a8641SAndroid Build Coastguard Worker
590*635a8641SAndroid Build Coastguard Worker // Update trace config for recording.
591*635a8641SAndroid Build Coastguard Worker const bool already_recording = enabled_modes_ & RECORDING_MODE;
592*635a8641SAndroid Build Coastguard Worker if (modes_to_enable & RECORDING_MODE) {
593*635a8641SAndroid Build Coastguard Worker if (already_recording) {
594*635a8641SAndroid Build Coastguard Worker // TODO(ssid): Stop suporting enabling of RECODING_MODE when already
595*635a8641SAndroid Build Coastguard Worker // enabled crbug.com/625170.
596*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(new_options, old_options) << "Attempting to re-enable "
597*635a8641SAndroid Build Coastguard Worker "tracing with a different set "
598*635a8641SAndroid Build Coastguard Worker "of options.";
599*635a8641SAndroid Build Coastguard Worker trace_config_.Merge(trace_config);
600*635a8641SAndroid Build Coastguard Worker } else {
601*635a8641SAndroid Build Coastguard Worker trace_config_ = trace_config;
602*635a8641SAndroid Build Coastguard Worker }
603*635a8641SAndroid Build Coastguard Worker }
604*635a8641SAndroid Build Coastguard Worker
605*635a8641SAndroid Build Coastguard Worker // Update event filters only if filtering was not enabled.
606*635a8641SAndroid Build Coastguard Worker if (modes_to_enable & FILTERING_MODE && enabled_event_filters_.empty()) {
607*635a8641SAndroid Build Coastguard Worker DCHECK(!trace_config.event_filters().empty());
608*635a8641SAndroid Build Coastguard Worker enabled_event_filters_ = trace_config.event_filters();
609*635a8641SAndroid Build Coastguard Worker }
610*635a8641SAndroid Build Coastguard Worker // Keep the |trace_config_| updated with only enabled filters in case anyone
611*635a8641SAndroid Build Coastguard Worker // tries to read it using |GetCurrentTraceConfig| (even if filters are
612*635a8641SAndroid Build Coastguard Worker // empty).
613*635a8641SAndroid Build Coastguard Worker trace_config_.SetEventFilters(enabled_event_filters_);
614*635a8641SAndroid Build Coastguard Worker
615*635a8641SAndroid Build Coastguard Worker enabled_modes_ |= modes_to_enable;
616*635a8641SAndroid Build Coastguard Worker UpdateCategoryRegistry();
617*635a8641SAndroid Build Coastguard Worker
618*635a8641SAndroid Build Coastguard Worker // Do not notify observers or create trace buffer if only enabled for
619*635a8641SAndroid Build Coastguard Worker // filtering or if recording was already enabled.
620*635a8641SAndroid Build Coastguard Worker if (!(modes_to_enable & RECORDING_MODE) || already_recording)
621*635a8641SAndroid Build Coastguard Worker return;
622*635a8641SAndroid Build Coastguard Worker
623*635a8641SAndroid Build Coastguard Worker if (new_options != old_options) {
624*635a8641SAndroid Build Coastguard Worker subtle::NoBarrier_Store(&trace_options_, new_options);
625*635a8641SAndroid Build Coastguard Worker UseNextTraceBuffer();
626*635a8641SAndroid Build Coastguard Worker }
627*635a8641SAndroid Build Coastguard Worker
628*635a8641SAndroid Build Coastguard Worker num_traces_recorded_++;
629*635a8641SAndroid Build Coastguard Worker
630*635a8641SAndroid Build Coastguard Worker UpdateCategoryRegistry();
631*635a8641SAndroid Build Coastguard Worker
632*635a8641SAndroid Build Coastguard Worker dispatching_to_observer_list_ = true;
633*635a8641SAndroid Build Coastguard Worker observer_list = enabled_state_observer_list_;
634*635a8641SAndroid Build Coastguard Worker observer_map = async_observers_;
635*635a8641SAndroid Build Coastguard Worker }
636*635a8641SAndroid Build Coastguard Worker // Notify observers outside the lock in case they trigger trace events.
637*635a8641SAndroid Build Coastguard Worker for (EnabledStateObserver* observer : observer_list)
638*635a8641SAndroid Build Coastguard Worker observer->OnTraceLogEnabled();
639*635a8641SAndroid Build Coastguard Worker for (const auto& it : observer_map) {
640*635a8641SAndroid Build Coastguard Worker it.second.task_runner->PostTask(
641*635a8641SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&AsyncEnabledStateObserver::OnTraceLogEnabled,
642*635a8641SAndroid Build Coastguard Worker it.second.observer));
643*635a8641SAndroid Build Coastguard Worker }
644*635a8641SAndroid Build Coastguard Worker
645*635a8641SAndroid Build Coastguard Worker {
646*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
647*635a8641SAndroid Build Coastguard Worker dispatching_to_observer_list_ = false;
648*635a8641SAndroid Build Coastguard Worker }
649*635a8641SAndroid Build Coastguard Worker }
650*635a8641SAndroid Build Coastguard Worker
SetArgumentFilterPredicate(const ArgumentFilterPredicate & argument_filter_predicate)651*635a8641SAndroid Build Coastguard Worker void TraceLog::SetArgumentFilterPredicate(
652*635a8641SAndroid Build Coastguard Worker const ArgumentFilterPredicate& argument_filter_predicate) {
653*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
654*635a8641SAndroid Build Coastguard Worker DCHECK(!argument_filter_predicate.is_null());
655*635a8641SAndroid Build Coastguard Worker DCHECK(argument_filter_predicate_.is_null());
656*635a8641SAndroid Build Coastguard Worker argument_filter_predicate_ = argument_filter_predicate;
657*635a8641SAndroid Build Coastguard Worker }
658*635a8641SAndroid Build Coastguard Worker
GetInternalOptionsFromTraceConfig(const TraceConfig & config)659*635a8641SAndroid Build Coastguard Worker TraceLog::InternalTraceOptions TraceLog::GetInternalOptionsFromTraceConfig(
660*635a8641SAndroid Build Coastguard Worker const TraceConfig& config) {
661*635a8641SAndroid Build Coastguard Worker InternalTraceOptions ret = config.IsArgumentFilterEnabled()
662*635a8641SAndroid Build Coastguard Worker ? kInternalEnableArgumentFilter
663*635a8641SAndroid Build Coastguard Worker : kInternalNone;
664*635a8641SAndroid Build Coastguard Worker switch (config.GetTraceRecordMode()) {
665*635a8641SAndroid Build Coastguard Worker case RECORD_UNTIL_FULL:
666*635a8641SAndroid Build Coastguard Worker return ret | kInternalRecordUntilFull;
667*635a8641SAndroid Build Coastguard Worker case RECORD_CONTINUOUSLY:
668*635a8641SAndroid Build Coastguard Worker return ret | kInternalRecordContinuously;
669*635a8641SAndroid Build Coastguard Worker case ECHO_TO_CONSOLE:
670*635a8641SAndroid Build Coastguard Worker return ret | kInternalEchoToConsole;
671*635a8641SAndroid Build Coastguard Worker case RECORD_AS_MUCH_AS_POSSIBLE:
672*635a8641SAndroid Build Coastguard Worker return ret | kInternalRecordAsMuchAsPossible;
673*635a8641SAndroid Build Coastguard Worker }
674*635a8641SAndroid Build Coastguard Worker NOTREACHED();
675*635a8641SAndroid Build Coastguard Worker return kInternalNone;
676*635a8641SAndroid Build Coastguard Worker }
677*635a8641SAndroid Build Coastguard Worker
GetCurrentTraceConfig() const678*635a8641SAndroid Build Coastguard Worker TraceConfig TraceLog::GetCurrentTraceConfig() const {
679*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
680*635a8641SAndroid Build Coastguard Worker return trace_config_;
681*635a8641SAndroid Build Coastguard Worker }
682*635a8641SAndroid Build Coastguard Worker
SetDisabled()683*635a8641SAndroid Build Coastguard Worker void TraceLog::SetDisabled() {
684*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
685*635a8641SAndroid Build Coastguard Worker SetDisabledWhileLocked(RECORDING_MODE);
686*635a8641SAndroid Build Coastguard Worker }
687*635a8641SAndroid Build Coastguard Worker
SetDisabled(uint8_t modes_to_disable)688*635a8641SAndroid Build Coastguard Worker void TraceLog::SetDisabled(uint8_t modes_to_disable) {
689*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
690*635a8641SAndroid Build Coastguard Worker SetDisabledWhileLocked(modes_to_disable);
691*635a8641SAndroid Build Coastguard Worker }
692*635a8641SAndroid Build Coastguard Worker
SetDisabledWhileLocked(uint8_t modes_to_disable)693*635a8641SAndroid Build Coastguard Worker void TraceLog::SetDisabledWhileLocked(uint8_t modes_to_disable) {
694*635a8641SAndroid Build Coastguard Worker lock_.AssertAcquired();
695*635a8641SAndroid Build Coastguard Worker
696*635a8641SAndroid Build Coastguard Worker if (!(enabled_modes_ & modes_to_disable))
697*635a8641SAndroid Build Coastguard Worker return;
698*635a8641SAndroid Build Coastguard Worker
699*635a8641SAndroid Build Coastguard Worker if (dispatching_to_observer_list_) {
700*635a8641SAndroid Build Coastguard Worker // TODO(ssid): Change to NOTREACHED after fixing crbug.com/625170.
701*635a8641SAndroid Build Coastguard Worker DLOG(ERROR)
702*635a8641SAndroid Build Coastguard Worker << "Cannot manipulate TraceLog::Enabled state from an observer.";
703*635a8641SAndroid Build Coastguard Worker return;
704*635a8641SAndroid Build Coastguard Worker }
705*635a8641SAndroid Build Coastguard Worker
706*635a8641SAndroid Build Coastguard Worker bool is_recording_mode_disabled =
707*635a8641SAndroid Build Coastguard Worker (enabled_modes_ & RECORDING_MODE) && (modes_to_disable & RECORDING_MODE);
708*635a8641SAndroid Build Coastguard Worker enabled_modes_ &= ~modes_to_disable;
709*635a8641SAndroid Build Coastguard Worker
710*635a8641SAndroid Build Coastguard Worker if (modes_to_disable & FILTERING_MODE)
711*635a8641SAndroid Build Coastguard Worker enabled_event_filters_.clear();
712*635a8641SAndroid Build Coastguard Worker
713*635a8641SAndroid Build Coastguard Worker if (modes_to_disable & RECORDING_MODE)
714*635a8641SAndroid Build Coastguard Worker trace_config_.Clear();
715*635a8641SAndroid Build Coastguard Worker
716*635a8641SAndroid Build Coastguard Worker UpdateCategoryRegistry();
717*635a8641SAndroid Build Coastguard Worker
718*635a8641SAndroid Build Coastguard Worker // Add metadata events and notify observers only if recording mode was
719*635a8641SAndroid Build Coastguard Worker // disabled now.
720*635a8641SAndroid Build Coastguard Worker if (!is_recording_mode_disabled)
721*635a8641SAndroid Build Coastguard Worker return;
722*635a8641SAndroid Build Coastguard Worker
723*635a8641SAndroid Build Coastguard Worker AddMetadataEventsWhileLocked();
724*635a8641SAndroid Build Coastguard Worker
725*635a8641SAndroid Build Coastguard Worker // Remove metadata events so they will not get added to a subsequent trace.
726*635a8641SAndroid Build Coastguard Worker metadata_events_.clear();
727*635a8641SAndroid Build Coastguard Worker
728*635a8641SAndroid Build Coastguard Worker dispatching_to_observer_list_ = true;
729*635a8641SAndroid Build Coastguard Worker std::vector<EnabledStateObserver*> observer_list =
730*635a8641SAndroid Build Coastguard Worker enabled_state_observer_list_;
731*635a8641SAndroid Build Coastguard Worker std::map<AsyncEnabledStateObserver*, RegisteredAsyncObserver> observer_map =
732*635a8641SAndroid Build Coastguard Worker async_observers_;
733*635a8641SAndroid Build Coastguard Worker
734*635a8641SAndroid Build Coastguard Worker {
735*635a8641SAndroid Build Coastguard Worker // Dispatch to observers outside the lock in case the observer triggers a
736*635a8641SAndroid Build Coastguard Worker // trace event.
737*635a8641SAndroid Build Coastguard Worker AutoUnlock unlock(lock_);
738*635a8641SAndroid Build Coastguard Worker for (EnabledStateObserver* observer : observer_list)
739*635a8641SAndroid Build Coastguard Worker observer->OnTraceLogDisabled();
740*635a8641SAndroid Build Coastguard Worker for (const auto& it : observer_map) {
741*635a8641SAndroid Build Coastguard Worker it.second.task_runner->PostTask(
742*635a8641SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&AsyncEnabledStateObserver::OnTraceLogDisabled,
743*635a8641SAndroid Build Coastguard Worker it.second.observer));
744*635a8641SAndroid Build Coastguard Worker }
745*635a8641SAndroid Build Coastguard Worker }
746*635a8641SAndroid Build Coastguard Worker dispatching_to_observer_list_ = false;
747*635a8641SAndroid Build Coastguard Worker }
748*635a8641SAndroid Build Coastguard Worker
GetNumTracesRecorded()749*635a8641SAndroid Build Coastguard Worker int TraceLog::GetNumTracesRecorded() {
750*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
751*635a8641SAndroid Build Coastguard Worker if (!IsEnabled())
752*635a8641SAndroid Build Coastguard Worker return -1;
753*635a8641SAndroid Build Coastguard Worker return num_traces_recorded_;
754*635a8641SAndroid Build Coastguard Worker }
755*635a8641SAndroid Build Coastguard Worker
AddEnabledStateObserver(EnabledStateObserver * listener)756*635a8641SAndroid Build Coastguard Worker void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) {
757*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
758*635a8641SAndroid Build Coastguard Worker enabled_state_observer_list_.push_back(listener);
759*635a8641SAndroid Build Coastguard Worker }
760*635a8641SAndroid Build Coastguard Worker
RemoveEnabledStateObserver(EnabledStateObserver * listener)761*635a8641SAndroid Build Coastguard Worker void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) {
762*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
763*635a8641SAndroid Build Coastguard Worker std::vector<EnabledStateObserver*>::iterator it =
764*635a8641SAndroid Build Coastguard Worker std::find(enabled_state_observer_list_.begin(),
765*635a8641SAndroid Build Coastguard Worker enabled_state_observer_list_.end(), listener);
766*635a8641SAndroid Build Coastguard Worker if (it != enabled_state_observer_list_.end())
767*635a8641SAndroid Build Coastguard Worker enabled_state_observer_list_.erase(it);
768*635a8641SAndroid Build Coastguard Worker }
769*635a8641SAndroid Build Coastguard Worker
HasEnabledStateObserver(EnabledStateObserver * listener) const770*635a8641SAndroid Build Coastguard Worker bool TraceLog::HasEnabledStateObserver(EnabledStateObserver* listener) const {
771*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
772*635a8641SAndroid Build Coastguard Worker return ContainsValue(enabled_state_observer_list_, listener);
773*635a8641SAndroid Build Coastguard Worker }
774*635a8641SAndroid Build Coastguard Worker
GetStatus() const775*635a8641SAndroid Build Coastguard Worker TraceLogStatus TraceLog::GetStatus() const {
776*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
777*635a8641SAndroid Build Coastguard Worker TraceLogStatus result;
778*635a8641SAndroid Build Coastguard Worker result.event_capacity = static_cast<uint32_t>(logged_events_->Capacity());
779*635a8641SAndroid Build Coastguard Worker result.event_count = static_cast<uint32_t>(logged_events_->Size());
780*635a8641SAndroid Build Coastguard Worker return result;
781*635a8641SAndroid Build Coastguard Worker }
782*635a8641SAndroid Build Coastguard Worker
BufferIsFull() const783*635a8641SAndroid Build Coastguard Worker bool TraceLog::BufferIsFull() const {
784*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
785*635a8641SAndroid Build Coastguard Worker return logged_events_->IsFull();
786*635a8641SAndroid Build Coastguard Worker }
787*635a8641SAndroid Build Coastguard Worker
AddEventToThreadSharedChunkWhileLocked(TraceEventHandle * handle,bool check_buffer_is_full)788*635a8641SAndroid Build Coastguard Worker TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked(
789*635a8641SAndroid Build Coastguard Worker TraceEventHandle* handle,
790*635a8641SAndroid Build Coastguard Worker bool check_buffer_is_full) {
791*635a8641SAndroid Build Coastguard Worker lock_.AssertAcquired();
792*635a8641SAndroid Build Coastguard Worker
793*635a8641SAndroid Build Coastguard Worker if (thread_shared_chunk_ && thread_shared_chunk_->IsFull()) {
794*635a8641SAndroid Build Coastguard Worker logged_events_->ReturnChunk(thread_shared_chunk_index_,
795*635a8641SAndroid Build Coastguard Worker std::move(thread_shared_chunk_));
796*635a8641SAndroid Build Coastguard Worker }
797*635a8641SAndroid Build Coastguard Worker
798*635a8641SAndroid Build Coastguard Worker if (!thread_shared_chunk_) {
799*635a8641SAndroid Build Coastguard Worker thread_shared_chunk_ =
800*635a8641SAndroid Build Coastguard Worker logged_events_->GetChunk(&thread_shared_chunk_index_);
801*635a8641SAndroid Build Coastguard Worker if (check_buffer_is_full)
802*635a8641SAndroid Build Coastguard Worker CheckIfBufferIsFullWhileLocked();
803*635a8641SAndroid Build Coastguard Worker }
804*635a8641SAndroid Build Coastguard Worker if (!thread_shared_chunk_)
805*635a8641SAndroid Build Coastguard Worker return nullptr;
806*635a8641SAndroid Build Coastguard Worker
807*635a8641SAndroid Build Coastguard Worker size_t event_index;
808*635a8641SAndroid Build Coastguard Worker TraceEvent* trace_event = thread_shared_chunk_->AddTraceEvent(&event_index);
809*635a8641SAndroid Build Coastguard Worker if (trace_event && handle) {
810*635a8641SAndroid Build Coastguard Worker MakeHandle(thread_shared_chunk_->seq(), thread_shared_chunk_index_,
811*635a8641SAndroid Build Coastguard Worker event_index, handle);
812*635a8641SAndroid Build Coastguard Worker }
813*635a8641SAndroid Build Coastguard Worker return trace_event;
814*635a8641SAndroid Build Coastguard Worker }
815*635a8641SAndroid Build Coastguard Worker
CheckIfBufferIsFullWhileLocked()816*635a8641SAndroid Build Coastguard Worker void TraceLog::CheckIfBufferIsFullWhileLocked() {
817*635a8641SAndroid Build Coastguard Worker lock_.AssertAcquired();
818*635a8641SAndroid Build Coastguard Worker if (logged_events_->IsFull()) {
819*635a8641SAndroid Build Coastguard Worker if (buffer_limit_reached_timestamp_.is_null()) {
820*635a8641SAndroid Build Coastguard Worker buffer_limit_reached_timestamp_ = OffsetNow();
821*635a8641SAndroid Build Coastguard Worker }
822*635a8641SAndroid Build Coastguard Worker SetDisabledWhileLocked(RECORDING_MODE);
823*635a8641SAndroid Build Coastguard Worker }
824*635a8641SAndroid Build Coastguard Worker }
825*635a8641SAndroid Build Coastguard Worker
826*635a8641SAndroid Build Coastguard Worker // Flush() works as the following:
827*635a8641SAndroid Build Coastguard Worker // 1. Flush() is called in thread A whose task runner is saved in
828*635a8641SAndroid Build Coastguard Worker // flush_task_runner_;
829*635a8641SAndroid Build Coastguard Worker // 2. If thread_message_loops_ is not empty, thread A posts task to each message
830*635a8641SAndroid Build Coastguard Worker // loop to flush the thread local buffers; otherwise finish the flush;
831*635a8641SAndroid Build Coastguard Worker // 3. FlushCurrentThread() deletes the thread local event buffer:
832*635a8641SAndroid Build Coastguard Worker // - The last batch of events of the thread are flushed into the main buffer;
833*635a8641SAndroid Build Coastguard Worker // - The message loop will be removed from thread_message_loops_;
834*635a8641SAndroid Build Coastguard Worker // If this is the last message loop, finish the flush;
835*635a8641SAndroid 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)836*635a8641SAndroid Build Coastguard Worker void TraceLog::Flush(const TraceLog::OutputCallback& cb,
837*635a8641SAndroid Build Coastguard Worker bool use_worker_thread) {
838*635a8641SAndroid Build Coastguard Worker FlushInternal(cb, use_worker_thread, false);
839*635a8641SAndroid Build Coastguard Worker }
840*635a8641SAndroid Build Coastguard Worker
CancelTracing(const OutputCallback & cb)841*635a8641SAndroid Build Coastguard Worker void TraceLog::CancelTracing(const OutputCallback& cb) {
842*635a8641SAndroid Build Coastguard Worker SetDisabled();
843*635a8641SAndroid Build Coastguard Worker FlushInternal(cb, false, true);
844*635a8641SAndroid Build Coastguard Worker }
845*635a8641SAndroid Build Coastguard Worker
FlushInternal(const TraceLog::OutputCallback & cb,bool use_worker_thread,bool discard_events)846*635a8641SAndroid Build Coastguard Worker void TraceLog::FlushInternal(const TraceLog::OutputCallback& cb,
847*635a8641SAndroid Build Coastguard Worker bool use_worker_thread,
848*635a8641SAndroid Build Coastguard Worker bool discard_events) {
849*635a8641SAndroid Build Coastguard Worker use_worker_thread_ = use_worker_thread;
850*635a8641SAndroid Build Coastguard Worker if (IsEnabled()) {
851*635a8641SAndroid Build Coastguard Worker // Can't flush when tracing is enabled because otherwise PostTask would
852*635a8641SAndroid Build Coastguard Worker // - generate more trace events;
853*635a8641SAndroid Build Coastguard Worker // - deschedule the calling thread on some platforms causing inaccurate
854*635a8641SAndroid Build Coastguard Worker // timing of the trace events.
855*635a8641SAndroid Build Coastguard Worker scoped_refptr<RefCountedString> empty_result = new RefCountedString;
856*635a8641SAndroid Build Coastguard Worker if (!cb.is_null())
857*635a8641SAndroid Build Coastguard Worker cb.Run(empty_result, false);
858*635a8641SAndroid Build Coastguard Worker LOG(WARNING) << "Ignored TraceLog::Flush called when tracing is enabled";
859*635a8641SAndroid Build Coastguard Worker return;
860*635a8641SAndroid Build Coastguard Worker }
861*635a8641SAndroid Build Coastguard Worker
862*635a8641SAndroid Build Coastguard Worker int gen = generation();
863*635a8641SAndroid Build Coastguard Worker // Copy of thread_message_loops_ to be used without locking.
864*635a8641SAndroid Build Coastguard Worker std::vector<scoped_refptr<SingleThreadTaskRunner>>
865*635a8641SAndroid Build Coastguard Worker thread_message_loop_task_runners;
866*635a8641SAndroid Build Coastguard Worker {
867*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
868*635a8641SAndroid Build Coastguard Worker DCHECK(!flush_task_runner_);
869*635a8641SAndroid Build Coastguard Worker flush_task_runner_ = SequencedTaskRunnerHandle::IsSet()
870*635a8641SAndroid Build Coastguard Worker ? SequencedTaskRunnerHandle::Get()
871*635a8641SAndroid Build Coastguard Worker : nullptr;
872*635a8641SAndroid Build Coastguard Worker DCHECK(thread_message_loops_.empty() || flush_task_runner_);
873*635a8641SAndroid Build Coastguard Worker flush_output_callback_ = cb;
874*635a8641SAndroid Build Coastguard Worker
875*635a8641SAndroid Build Coastguard Worker if (thread_shared_chunk_) {
876*635a8641SAndroid Build Coastguard Worker logged_events_->ReturnChunk(thread_shared_chunk_index_,
877*635a8641SAndroid Build Coastguard Worker std::move(thread_shared_chunk_));
878*635a8641SAndroid Build Coastguard Worker }
879*635a8641SAndroid Build Coastguard Worker
880*635a8641SAndroid Build Coastguard Worker for (MessageLoop* loop : thread_message_loops_)
881*635a8641SAndroid Build Coastguard Worker thread_message_loop_task_runners.push_back(loop->task_runner());
882*635a8641SAndroid Build Coastguard Worker }
883*635a8641SAndroid Build Coastguard Worker
884*635a8641SAndroid Build Coastguard Worker if (!thread_message_loop_task_runners.empty()) {
885*635a8641SAndroid Build Coastguard Worker for (auto& task_runner : thread_message_loop_task_runners) {
886*635a8641SAndroid Build Coastguard Worker task_runner->PostTask(
887*635a8641SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&TraceLog::FlushCurrentThread, Unretained(this),
888*635a8641SAndroid Build Coastguard Worker gen, discard_events));
889*635a8641SAndroid Build Coastguard Worker }
890*635a8641SAndroid Build Coastguard Worker flush_task_runner_->PostDelayedTask(
891*635a8641SAndroid Build Coastguard Worker FROM_HERE,
892*635a8641SAndroid Build Coastguard Worker BindOnce(&TraceLog::OnFlushTimeout, Unretained(this), gen,
893*635a8641SAndroid Build Coastguard Worker discard_events),
894*635a8641SAndroid Build Coastguard Worker TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs));
895*635a8641SAndroid Build Coastguard Worker return;
896*635a8641SAndroid Build Coastguard Worker }
897*635a8641SAndroid Build Coastguard Worker
898*635a8641SAndroid Build Coastguard Worker FinishFlush(gen, discard_events);
899*635a8641SAndroid Build Coastguard Worker }
900*635a8641SAndroid Build Coastguard Worker
901*635a8641SAndroid 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)902*635a8641SAndroid Build Coastguard Worker void TraceLog::ConvertTraceEventsToTraceFormat(
903*635a8641SAndroid Build Coastguard Worker std::unique_ptr<TraceBuffer> logged_events,
904*635a8641SAndroid Build Coastguard Worker const OutputCallback& flush_output_callback,
905*635a8641SAndroid Build Coastguard Worker const ArgumentFilterPredicate& argument_filter_predicate) {
906*635a8641SAndroid Build Coastguard Worker if (flush_output_callback.is_null())
907*635a8641SAndroid Build Coastguard Worker return;
908*635a8641SAndroid Build Coastguard Worker
909*635a8641SAndroid Build Coastguard Worker HEAP_PROFILER_SCOPED_IGNORE;
910*635a8641SAndroid Build Coastguard Worker // The callback need to be called at least once even if there is no events
911*635a8641SAndroid Build Coastguard Worker // to let the caller know the completion of flush.
912*635a8641SAndroid Build Coastguard Worker scoped_refptr<RefCountedString> json_events_str_ptr = new RefCountedString();
913*635a8641SAndroid Build Coastguard Worker const size_t kReserveCapacity = kTraceEventBufferSizeInBytes * 5 / 4;
914*635a8641SAndroid Build Coastguard Worker json_events_str_ptr->data().reserve(kReserveCapacity);
915*635a8641SAndroid Build Coastguard Worker while (const TraceBufferChunk* chunk = logged_events->NextChunk()) {
916*635a8641SAndroid Build Coastguard Worker for (size_t j = 0; j < chunk->size(); ++j) {
917*635a8641SAndroid Build Coastguard Worker size_t size = json_events_str_ptr->size();
918*635a8641SAndroid Build Coastguard Worker if (size > kTraceEventBufferSizeInBytes) {
919*635a8641SAndroid Build Coastguard Worker flush_output_callback.Run(json_events_str_ptr, true);
920*635a8641SAndroid Build Coastguard Worker json_events_str_ptr = new RefCountedString();
921*635a8641SAndroid Build Coastguard Worker json_events_str_ptr->data().reserve(kReserveCapacity);
922*635a8641SAndroid Build Coastguard Worker } else if (size) {
923*635a8641SAndroid Build Coastguard Worker json_events_str_ptr->data().append(",\n");
924*635a8641SAndroid Build Coastguard Worker }
925*635a8641SAndroid Build Coastguard Worker chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data()),
926*635a8641SAndroid Build Coastguard Worker argument_filter_predicate);
927*635a8641SAndroid Build Coastguard Worker }
928*635a8641SAndroid Build Coastguard Worker }
929*635a8641SAndroid Build Coastguard Worker flush_output_callback.Run(json_events_str_ptr, false);
930*635a8641SAndroid Build Coastguard Worker }
931*635a8641SAndroid Build Coastguard Worker
FinishFlush(int generation,bool discard_events)932*635a8641SAndroid Build Coastguard Worker void TraceLog::FinishFlush(int generation, bool discard_events) {
933*635a8641SAndroid Build Coastguard Worker std::unique_ptr<TraceBuffer> previous_logged_events;
934*635a8641SAndroid Build Coastguard Worker OutputCallback flush_output_callback;
935*635a8641SAndroid Build Coastguard Worker ArgumentFilterPredicate argument_filter_predicate;
936*635a8641SAndroid Build Coastguard Worker
937*635a8641SAndroid Build Coastguard Worker if (!CheckGeneration(generation))
938*635a8641SAndroid Build Coastguard Worker return;
939*635a8641SAndroid Build Coastguard Worker
940*635a8641SAndroid Build Coastguard Worker {
941*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
942*635a8641SAndroid Build Coastguard Worker
943*635a8641SAndroid Build Coastguard Worker previous_logged_events.swap(logged_events_);
944*635a8641SAndroid Build Coastguard Worker UseNextTraceBuffer();
945*635a8641SAndroid Build Coastguard Worker thread_message_loops_.clear();
946*635a8641SAndroid Build Coastguard Worker
947*635a8641SAndroid Build Coastguard Worker flush_task_runner_ = nullptr;
948*635a8641SAndroid Build Coastguard Worker flush_output_callback = flush_output_callback_;
949*635a8641SAndroid Build Coastguard Worker flush_output_callback_.Reset();
950*635a8641SAndroid Build Coastguard Worker
951*635a8641SAndroid Build Coastguard Worker if (trace_options() & kInternalEnableArgumentFilter) {
952*635a8641SAndroid Build Coastguard Worker CHECK(!argument_filter_predicate_.is_null());
953*635a8641SAndroid Build Coastguard Worker argument_filter_predicate = argument_filter_predicate_;
954*635a8641SAndroid Build Coastguard Worker }
955*635a8641SAndroid Build Coastguard Worker }
956*635a8641SAndroid Build Coastguard Worker
957*635a8641SAndroid Build Coastguard Worker if (discard_events) {
958*635a8641SAndroid Build Coastguard Worker if (!flush_output_callback.is_null()) {
959*635a8641SAndroid Build Coastguard Worker scoped_refptr<RefCountedString> empty_result = new RefCountedString;
960*635a8641SAndroid Build Coastguard Worker flush_output_callback.Run(empty_result, false);
961*635a8641SAndroid Build Coastguard Worker }
962*635a8641SAndroid Build Coastguard Worker return;
963*635a8641SAndroid Build Coastguard Worker }
964*635a8641SAndroid Build Coastguard Worker
965*635a8641SAndroid Build Coastguard Worker if (use_worker_thread_) {
966*635a8641SAndroid Build Coastguard Worker base::PostTaskWithTraits(
967*635a8641SAndroid Build Coastguard Worker FROM_HERE,
968*635a8641SAndroid Build Coastguard Worker {MayBlock(), TaskPriority::BACKGROUND,
969*635a8641SAndroid Build Coastguard Worker TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
970*635a8641SAndroid Build Coastguard Worker BindOnce(&TraceLog::ConvertTraceEventsToTraceFormat,
971*635a8641SAndroid Build Coastguard Worker std::move(previous_logged_events), flush_output_callback,
972*635a8641SAndroid Build Coastguard Worker argument_filter_predicate));
973*635a8641SAndroid Build Coastguard Worker return;
974*635a8641SAndroid Build Coastguard Worker }
975*635a8641SAndroid Build Coastguard Worker
976*635a8641SAndroid Build Coastguard Worker ConvertTraceEventsToTraceFormat(std::move(previous_logged_events),
977*635a8641SAndroid Build Coastguard Worker flush_output_callback,
978*635a8641SAndroid Build Coastguard Worker argument_filter_predicate);
979*635a8641SAndroid Build Coastguard Worker }
980*635a8641SAndroid Build Coastguard Worker
981*635a8641SAndroid Build Coastguard Worker // Run in each thread holding a local event buffer.
FlushCurrentThread(int generation,bool discard_events)982*635a8641SAndroid Build Coastguard Worker void TraceLog::FlushCurrentThread(int generation, bool discard_events) {
983*635a8641SAndroid Build Coastguard Worker {
984*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
985*635a8641SAndroid Build Coastguard Worker if (!CheckGeneration(generation) || !flush_task_runner_) {
986*635a8641SAndroid Build Coastguard Worker // This is late. The corresponding flush has finished.
987*635a8641SAndroid Build Coastguard Worker return;
988*635a8641SAndroid Build Coastguard Worker }
989*635a8641SAndroid Build Coastguard Worker }
990*635a8641SAndroid Build Coastguard Worker
991*635a8641SAndroid Build Coastguard Worker // This will flush the thread local buffer.
992*635a8641SAndroid Build Coastguard Worker delete thread_local_event_buffer_.Get();
993*635a8641SAndroid Build Coastguard Worker
994*635a8641SAndroid Build Coastguard Worker // Scheduler uses TRACE_EVENT macros when posting a task, which can lead
995*635a8641SAndroid Build Coastguard Worker // to acquiring a tracing lock. Given that posting a task requires grabbing
996*635a8641SAndroid Build Coastguard Worker // a scheduler lock, we need to post this task outside tracing lock to avoid
997*635a8641SAndroid Build Coastguard Worker // deadlocks.
998*635a8641SAndroid Build Coastguard Worker scoped_refptr<SequencedTaskRunner> cached_flush_task_runner;
999*635a8641SAndroid Build Coastguard Worker {
1000*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1001*635a8641SAndroid Build Coastguard Worker cached_flush_task_runner = flush_task_runner_;
1002*635a8641SAndroid Build Coastguard Worker if (!CheckGeneration(generation) || !flush_task_runner_ ||
1003*635a8641SAndroid Build Coastguard Worker !thread_message_loops_.empty())
1004*635a8641SAndroid Build Coastguard Worker return;
1005*635a8641SAndroid Build Coastguard Worker }
1006*635a8641SAndroid Build Coastguard Worker cached_flush_task_runner->PostTask(
1007*635a8641SAndroid Build Coastguard Worker FROM_HERE, BindOnce(&TraceLog::FinishFlush, Unretained(this), generation,
1008*635a8641SAndroid Build Coastguard Worker discard_events));
1009*635a8641SAndroid Build Coastguard Worker }
1010*635a8641SAndroid Build Coastguard Worker
OnFlushTimeout(int generation,bool discard_events)1011*635a8641SAndroid Build Coastguard Worker void TraceLog::OnFlushTimeout(int generation, bool discard_events) {
1012*635a8641SAndroid Build Coastguard Worker {
1013*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1014*635a8641SAndroid Build Coastguard Worker if (!CheckGeneration(generation) || !flush_task_runner_) {
1015*635a8641SAndroid Build Coastguard Worker // Flush has finished before timeout.
1016*635a8641SAndroid Build Coastguard Worker return;
1017*635a8641SAndroid Build Coastguard Worker }
1018*635a8641SAndroid Build Coastguard Worker
1019*635a8641SAndroid Build Coastguard Worker LOG(WARNING)
1020*635a8641SAndroid Build Coastguard Worker << "The following threads haven't finished flush in time. "
1021*635a8641SAndroid Build Coastguard Worker "If this happens stably for some thread, please call "
1022*635a8641SAndroid Build Coastguard Worker "TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop() from "
1023*635a8641SAndroid Build Coastguard Worker "the thread to avoid its trace events from being lost.";
1024*635a8641SAndroid Build Coastguard Worker for (hash_set<MessageLoop*>::const_iterator it =
1025*635a8641SAndroid Build Coastguard Worker thread_message_loops_.begin();
1026*635a8641SAndroid Build Coastguard Worker it != thread_message_loops_.end(); ++it) {
1027*635a8641SAndroid Build Coastguard Worker LOG(WARNING) << "Thread: " << (*it)->GetThreadName();
1028*635a8641SAndroid Build Coastguard Worker }
1029*635a8641SAndroid Build Coastguard Worker }
1030*635a8641SAndroid Build Coastguard Worker FinishFlush(generation, discard_events);
1031*635a8641SAndroid Build Coastguard Worker }
1032*635a8641SAndroid Build Coastguard Worker
UseNextTraceBuffer()1033*635a8641SAndroid Build Coastguard Worker void TraceLog::UseNextTraceBuffer() {
1034*635a8641SAndroid Build Coastguard Worker logged_events_.reset(CreateTraceBuffer());
1035*635a8641SAndroid Build Coastguard Worker subtle::NoBarrier_AtomicIncrement(&generation_, 1);
1036*635a8641SAndroid Build Coastguard Worker thread_shared_chunk_.reset();
1037*635a8641SAndroid Build Coastguard Worker thread_shared_chunk_index_ = 0;
1038*635a8641SAndroid Build Coastguard Worker }
1039*635a8641SAndroid Build Coastguard Worker
AddTraceEvent(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,unsigned long long id,int num_args,const char * const * arg_names,const unsigned char * arg_types,const unsigned long long * arg_values,std::unique_ptr<ConvertableToTraceFormat> * convertable_values,unsigned int flags)1040*635a8641SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEvent(
1041*635a8641SAndroid Build Coastguard Worker char phase,
1042*635a8641SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1043*635a8641SAndroid Build Coastguard Worker const char* name,
1044*635a8641SAndroid Build Coastguard Worker const char* scope,
1045*635a8641SAndroid Build Coastguard Worker unsigned long long id,
1046*635a8641SAndroid Build Coastguard Worker int num_args,
1047*635a8641SAndroid Build Coastguard Worker const char* const* arg_names,
1048*635a8641SAndroid Build Coastguard Worker const unsigned char* arg_types,
1049*635a8641SAndroid Build Coastguard Worker const unsigned long long* arg_values,
1050*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
1051*635a8641SAndroid Build Coastguard Worker unsigned int flags) {
1052*635a8641SAndroid Build Coastguard Worker int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1053*635a8641SAndroid Build Coastguard Worker base::TimeTicks now = TRACE_TIME_TICKS_NOW();
1054*635a8641SAndroid Build Coastguard Worker return AddTraceEventWithThreadIdAndTimestamp(
1055*635a8641SAndroid Build Coastguard Worker phase,
1056*635a8641SAndroid Build Coastguard Worker category_group_enabled,
1057*635a8641SAndroid Build Coastguard Worker name,
1058*635a8641SAndroid Build Coastguard Worker scope,
1059*635a8641SAndroid Build Coastguard Worker id,
1060*635a8641SAndroid Build Coastguard Worker trace_event_internal::kNoId, // bind_id
1061*635a8641SAndroid Build Coastguard Worker thread_id,
1062*635a8641SAndroid Build Coastguard Worker now,
1063*635a8641SAndroid Build Coastguard Worker num_args,
1064*635a8641SAndroid Build Coastguard Worker arg_names,
1065*635a8641SAndroid Build Coastguard Worker arg_types,
1066*635a8641SAndroid Build Coastguard Worker arg_values,
1067*635a8641SAndroid Build Coastguard Worker convertable_values,
1068*635a8641SAndroid Build Coastguard Worker flags);
1069*635a8641SAndroid Build Coastguard Worker }
1070*635a8641SAndroid Build Coastguard Worker
AddTraceEventWithBindId(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,unsigned long long id,unsigned long long bind_id,int num_args,const char * const * arg_names,const unsigned char * arg_types,const unsigned long long * arg_values,std::unique_ptr<ConvertableToTraceFormat> * convertable_values,unsigned int flags)1071*635a8641SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEventWithBindId(
1072*635a8641SAndroid Build Coastguard Worker char phase,
1073*635a8641SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1074*635a8641SAndroid Build Coastguard Worker const char* name,
1075*635a8641SAndroid Build Coastguard Worker const char* scope,
1076*635a8641SAndroid Build Coastguard Worker unsigned long long id,
1077*635a8641SAndroid Build Coastguard Worker unsigned long long bind_id,
1078*635a8641SAndroid Build Coastguard Worker int num_args,
1079*635a8641SAndroid Build Coastguard Worker const char* const* arg_names,
1080*635a8641SAndroid Build Coastguard Worker const unsigned char* arg_types,
1081*635a8641SAndroid Build Coastguard Worker const unsigned long long* arg_values,
1082*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
1083*635a8641SAndroid Build Coastguard Worker unsigned int flags) {
1084*635a8641SAndroid Build Coastguard Worker int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1085*635a8641SAndroid Build Coastguard Worker base::TimeTicks now = TRACE_TIME_TICKS_NOW();
1086*635a8641SAndroid Build Coastguard Worker return AddTraceEventWithThreadIdAndTimestamp(
1087*635a8641SAndroid Build Coastguard Worker phase,
1088*635a8641SAndroid Build Coastguard Worker category_group_enabled,
1089*635a8641SAndroid Build Coastguard Worker name,
1090*635a8641SAndroid Build Coastguard Worker scope,
1091*635a8641SAndroid Build Coastguard Worker id,
1092*635a8641SAndroid Build Coastguard Worker bind_id,
1093*635a8641SAndroid Build Coastguard Worker thread_id,
1094*635a8641SAndroid Build Coastguard Worker now,
1095*635a8641SAndroid Build Coastguard Worker num_args,
1096*635a8641SAndroid Build Coastguard Worker arg_names,
1097*635a8641SAndroid Build Coastguard Worker arg_types,
1098*635a8641SAndroid Build Coastguard Worker arg_values,
1099*635a8641SAndroid Build Coastguard Worker convertable_values,
1100*635a8641SAndroid Build Coastguard Worker flags | TRACE_EVENT_FLAG_HAS_CONTEXT_ID);
1101*635a8641SAndroid Build Coastguard Worker }
1102*635a8641SAndroid Build Coastguard Worker
AddTraceEventWithProcessId(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,unsigned long long id,int process_id,int num_args,const char * const * arg_names,const unsigned char * arg_types,const unsigned long long * arg_values,std::unique_ptr<ConvertableToTraceFormat> * convertable_values,unsigned int flags)1103*635a8641SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEventWithProcessId(
1104*635a8641SAndroid Build Coastguard Worker char phase,
1105*635a8641SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1106*635a8641SAndroid Build Coastguard Worker const char* name,
1107*635a8641SAndroid Build Coastguard Worker const char* scope,
1108*635a8641SAndroid Build Coastguard Worker unsigned long long id,
1109*635a8641SAndroid Build Coastguard Worker int process_id,
1110*635a8641SAndroid Build Coastguard Worker int num_args,
1111*635a8641SAndroid Build Coastguard Worker const char* const* arg_names,
1112*635a8641SAndroid Build Coastguard Worker const unsigned char* arg_types,
1113*635a8641SAndroid Build Coastguard Worker const unsigned long long* arg_values,
1114*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
1115*635a8641SAndroid Build Coastguard Worker unsigned int flags) {
1116*635a8641SAndroid Build Coastguard Worker base::TimeTicks now = TRACE_TIME_TICKS_NOW();
1117*635a8641SAndroid Build Coastguard Worker return AddTraceEventWithThreadIdAndTimestamp(
1118*635a8641SAndroid Build Coastguard Worker phase,
1119*635a8641SAndroid Build Coastguard Worker category_group_enabled,
1120*635a8641SAndroid Build Coastguard Worker name,
1121*635a8641SAndroid Build Coastguard Worker scope,
1122*635a8641SAndroid Build Coastguard Worker id,
1123*635a8641SAndroid Build Coastguard Worker trace_event_internal::kNoId, // bind_id
1124*635a8641SAndroid Build Coastguard Worker process_id,
1125*635a8641SAndroid Build Coastguard Worker now,
1126*635a8641SAndroid Build Coastguard Worker num_args,
1127*635a8641SAndroid Build Coastguard Worker arg_names,
1128*635a8641SAndroid Build Coastguard Worker arg_types,
1129*635a8641SAndroid Build Coastguard Worker arg_values,
1130*635a8641SAndroid Build Coastguard Worker convertable_values,
1131*635a8641SAndroid Build Coastguard Worker flags | TRACE_EVENT_FLAG_HAS_PROCESS_ID);
1132*635a8641SAndroid Build Coastguard Worker }
1133*635a8641SAndroid Build Coastguard Worker
1134*635a8641SAndroid Build Coastguard Worker // Handle legacy calls to AddTraceEventWithThreadIdAndTimestamp
1135*635a8641SAndroid Build Coastguard Worker // with kNoId as bind_id
AddTraceEventWithThreadIdAndTimestamp(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,unsigned long long id,int thread_id,const TimeTicks & timestamp,int num_args,const char * const * arg_names,const unsigned char * arg_types,const unsigned long long * arg_values,std::unique_ptr<ConvertableToTraceFormat> * convertable_values,unsigned int flags)1136*635a8641SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
1137*635a8641SAndroid Build Coastguard Worker char phase,
1138*635a8641SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1139*635a8641SAndroid Build Coastguard Worker const char* name,
1140*635a8641SAndroid Build Coastguard Worker const char* scope,
1141*635a8641SAndroid Build Coastguard Worker unsigned long long id,
1142*635a8641SAndroid Build Coastguard Worker int thread_id,
1143*635a8641SAndroid Build Coastguard Worker const TimeTicks& timestamp,
1144*635a8641SAndroid Build Coastguard Worker int num_args,
1145*635a8641SAndroid Build Coastguard Worker const char* const* arg_names,
1146*635a8641SAndroid Build Coastguard Worker const unsigned char* arg_types,
1147*635a8641SAndroid Build Coastguard Worker const unsigned long long* arg_values,
1148*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
1149*635a8641SAndroid Build Coastguard Worker unsigned int flags) {
1150*635a8641SAndroid Build Coastguard Worker return AddTraceEventWithThreadIdAndTimestamp(
1151*635a8641SAndroid Build Coastguard Worker phase,
1152*635a8641SAndroid Build Coastguard Worker category_group_enabled,
1153*635a8641SAndroid Build Coastguard Worker name,
1154*635a8641SAndroid Build Coastguard Worker scope,
1155*635a8641SAndroid Build Coastguard Worker id,
1156*635a8641SAndroid Build Coastguard Worker trace_event_internal::kNoId, // bind_id
1157*635a8641SAndroid Build Coastguard Worker thread_id,
1158*635a8641SAndroid Build Coastguard Worker timestamp,
1159*635a8641SAndroid Build Coastguard Worker num_args,
1160*635a8641SAndroid Build Coastguard Worker arg_names,
1161*635a8641SAndroid Build Coastguard Worker arg_types,
1162*635a8641SAndroid Build Coastguard Worker arg_values,
1163*635a8641SAndroid Build Coastguard Worker convertable_values,
1164*635a8641SAndroid Build Coastguard Worker flags);
1165*635a8641SAndroid Build Coastguard Worker }
1166*635a8641SAndroid Build Coastguard Worker
AddTraceEventWithThreadIdAndTimestamp(char phase,const unsigned char * category_group_enabled,const char * name,const char * scope,unsigned long long id,unsigned long long bind_id,int thread_id,const TimeTicks & timestamp,int num_args,const char * const * arg_names,const unsigned char * arg_types,const unsigned long long * arg_values,std::unique_ptr<ConvertableToTraceFormat> * convertable_values,unsigned int flags)1167*635a8641SAndroid Build Coastguard Worker TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp(
1168*635a8641SAndroid Build Coastguard Worker char phase,
1169*635a8641SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1170*635a8641SAndroid Build Coastguard Worker const char* name,
1171*635a8641SAndroid Build Coastguard Worker const char* scope,
1172*635a8641SAndroid Build Coastguard Worker unsigned long long id,
1173*635a8641SAndroid Build Coastguard Worker unsigned long long bind_id,
1174*635a8641SAndroid Build Coastguard Worker int thread_id,
1175*635a8641SAndroid Build Coastguard Worker const TimeTicks& timestamp,
1176*635a8641SAndroid Build Coastguard Worker int num_args,
1177*635a8641SAndroid Build Coastguard Worker const char* const* arg_names,
1178*635a8641SAndroid Build Coastguard Worker const unsigned char* arg_types,
1179*635a8641SAndroid Build Coastguard Worker const unsigned long long* arg_values,
1180*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
1181*635a8641SAndroid Build Coastguard Worker unsigned int flags) {
1182*635a8641SAndroid Build Coastguard Worker TraceEventHandle handle = {0, 0, 0};
1183*635a8641SAndroid Build Coastguard Worker if (!*category_group_enabled)
1184*635a8641SAndroid Build Coastguard Worker return handle;
1185*635a8641SAndroid Build Coastguard Worker
1186*635a8641SAndroid Build Coastguard Worker // Avoid re-entrance of AddTraceEvent. This may happen in GPU process when
1187*635a8641SAndroid Build Coastguard Worker // ECHO_TO_CONSOLE is enabled: AddTraceEvent -> LOG(ERROR) ->
1188*635a8641SAndroid Build Coastguard Worker // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ...
1189*635a8641SAndroid Build Coastguard Worker if (thread_is_in_trace_event_.Get())
1190*635a8641SAndroid Build Coastguard Worker return handle;
1191*635a8641SAndroid Build Coastguard Worker
1192*635a8641SAndroid Build Coastguard Worker AutoThreadLocalBoolean thread_is_in_trace_event(&thread_is_in_trace_event_);
1193*635a8641SAndroid Build Coastguard Worker
1194*635a8641SAndroid Build Coastguard Worker DCHECK(name);
1195*635a8641SAndroid Build Coastguard Worker DCHECK(!timestamp.is_null());
1196*635a8641SAndroid Build Coastguard Worker
1197*635a8641SAndroid Build Coastguard Worker if (flags & TRACE_EVENT_FLAG_MANGLE_ID) {
1198*635a8641SAndroid Build Coastguard Worker if ((flags & TRACE_EVENT_FLAG_FLOW_IN) ||
1199*635a8641SAndroid Build Coastguard Worker (flags & TRACE_EVENT_FLAG_FLOW_OUT))
1200*635a8641SAndroid Build Coastguard Worker bind_id = MangleEventId(bind_id);
1201*635a8641SAndroid Build Coastguard Worker id = MangleEventId(id);
1202*635a8641SAndroid Build Coastguard Worker }
1203*635a8641SAndroid Build Coastguard Worker
1204*635a8641SAndroid Build Coastguard Worker TimeTicks offset_event_timestamp = OffsetTimestamp(timestamp);
1205*635a8641SAndroid Build Coastguard Worker ThreadTicks thread_now = ThreadNow();
1206*635a8641SAndroid Build Coastguard Worker
1207*635a8641SAndroid Build Coastguard Worker ThreadLocalEventBuffer* thread_local_event_buffer = nullptr;
1208*635a8641SAndroid Build Coastguard Worker if (*category_group_enabled & RECORDING_MODE) {
1209*635a8641SAndroid Build Coastguard Worker // |thread_local_event_buffer_| can be null if the current thread doesn't
1210*635a8641SAndroid Build Coastguard Worker // have a message loop or the message loop is blocked.
1211*635a8641SAndroid Build Coastguard Worker InitializeThreadLocalEventBufferIfSupported();
1212*635a8641SAndroid Build Coastguard Worker thread_local_event_buffer = thread_local_event_buffer_.Get();
1213*635a8641SAndroid Build Coastguard Worker }
1214*635a8641SAndroid Build Coastguard Worker
1215*635a8641SAndroid Build Coastguard Worker // Check and update the current thread name only if the event is for the
1216*635a8641SAndroid Build Coastguard Worker // current thread to avoid locks in most cases.
1217*635a8641SAndroid Build Coastguard Worker if (thread_id == static_cast<int>(PlatformThread::CurrentId())) {
1218*635a8641SAndroid Build Coastguard Worker const char* new_name =
1219*635a8641SAndroid Build Coastguard Worker ThreadIdNameManager::GetInstance()->GetName(thread_id);
1220*635a8641SAndroid Build Coastguard Worker // Check if the thread name has been set or changed since the previous
1221*635a8641SAndroid Build Coastguard Worker // call (if any), but don't bother if the new name is empty. Note this will
1222*635a8641SAndroid Build Coastguard Worker // not detect a thread name change within the same char* buffer address: we
1223*635a8641SAndroid Build Coastguard Worker // favor common case performance over corner case correctness.
1224*635a8641SAndroid Build Coastguard Worker static auto* current_thread_name = new ThreadLocalPointer<const char>();
1225*635a8641SAndroid Build Coastguard Worker if (new_name != current_thread_name->Get() && new_name && *new_name) {
1226*635a8641SAndroid Build Coastguard Worker current_thread_name->Set(new_name);
1227*635a8641SAndroid Build Coastguard Worker
1228*635a8641SAndroid Build Coastguard Worker AutoLock thread_info_lock(thread_info_lock_);
1229*635a8641SAndroid Build Coastguard Worker
1230*635a8641SAndroid Build Coastguard Worker auto existing_name = thread_names_.find(thread_id);
1231*635a8641SAndroid Build Coastguard Worker if (existing_name == thread_names_.end()) {
1232*635a8641SAndroid Build Coastguard Worker // This is a new thread id, and a new name.
1233*635a8641SAndroid Build Coastguard Worker thread_names_[thread_id] = new_name;
1234*635a8641SAndroid Build Coastguard Worker } else {
1235*635a8641SAndroid Build Coastguard Worker // This is a thread id that we've seen before, but potentially with a
1236*635a8641SAndroid Build Coastguard Worker // new name.
1237*635a8641SAndroid Build Coastguard Worker std::vector<StringPiece> existing_names = base::SplitStringPiece(
1238*635a8641SAndroid Build Coastguard Worker existing_name->second, ",", base::KEEP_WHITESPACE,
1239*635a8641SAndroid Build Coastguard Worker base::SPLIT_WANT_NONEMPTY);
1240*635a8641SAndroid Build Coastguard Worker if (!ContainsValue(existing_names, new_name)) {
1241*635a8641SAndroid Build Coastguard Worker if (!existing_names.empty())
1242*635a8641SAndroid Build Coastguard Worker existing_name->second.push_back(',');
1243*635a8641SAndroid Build Coastguard Worker existing_name->second.append(new_name);
1244*635a8641SAndroid Build Coastguard Worker }
1245*635a8641SAndroid Build Coastguard Worker }
1246*635a8641SAndroid Build Coastguard Worker }
1247*635a8641SAndroid Build Coastguard Worker }
1248*635a8641SAndroid Build Coastguard Worker
1249*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
1250*635a8641SAndroid Build Coastguard Worker // This is done sooner rather than later, to avoid creating the event and
1251*635a8641SAndroid Build Coastguard Worker // acquiring the lock, which is not needed for ETW as it's already threadsafe.
1252*635a8641SAndroid Build Coastguard Worker if (*category_group_enabled & TraceCategory::ENABLED_FOR_ETW_EXPORT)
1253*635a8641SAndroid Build Coastguard Worker TraceEventETWExport::AddEvent(phase, category_group_enabled, name, id,
1254*635a8641SAndroid Build Coastguard Worker num_args, arg_names, arg_types, arg_values,
1255*635a8641SAndroid Build Coastguard Worker convertable_values);
1256*635a8641SAndroid Build Coastguard Worker #endif // OS_WIN
1257*635a8641SAndroid Build Coastguard Worker
1258*635a8641SAndroid Build Coastguard Worker AddTraceEventOverrideCallback trace_event_override =
1259*635a8641SAndroid Build Coastguard Worker reinterpret_cast<AddTraceEventOverrideCallback>(
1260*635a8641SAndroid Build Coastguard Worker subtle::NoBarrier_Load(&trace_event_override_));
1261*635a8641SAndroid Build Coastguard Worker if (trace_event_override) {
1262*635a8641SAndroid Build Coastguard Worker TraceEvent new_trace_event;
1263*635a8641SAndroid Build Coastguard Worker // If we have an override in place for events, rather than sending
1264*635a8641SAndroid Build Coastguard Worker // them to the tracelog, we don't have a way of going back and updating
1265*635a8641SAndroid Build Coastguard Worker // the duration of _COMPLETE events. Instead, we emit separate _BEGIN
1266*635a8641SAndroid Build Coastguard Worker // and _END events.
1267*635a8641SAndroid Build Coastguard Worker if (phase == TRACE_EVENT_PHASE_COMPLETE)
1268*635a8641SAndroid Build Coastguard Worker phase = TRACE_EVENT_PHASE_BEGIN;
1269*635a8641SAndroid Build Coastguard Worker
1270*635a8641SAndroid Build Coastguard Worker new_trace_event.Initialize(thread_id, offset_event_timestamp, thread_now,
1271*635a8641SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id,
1272*635a8641SAndroid Build Coastguard Worker bind_id, num_args, arg_names, arg_types,
1273*635a8641SAndroid Build Coastguard Worker arg_values, convertable_values, flags);
1274*635a8641SAndroid Build Coastguard Worker
1275*635a8641SAndroid Build Coastguard Worker trace_event_override(new_trace_event);
1276*635a8641SAndroid Build Coastguard Worker return handle;
1277*635a8641SAndroid Build Coastguard Worker }
1278*635a8641SAndroid Build Coastguard Worker
1279*635a8641SAndroid Build Coastguard Worker std::string console_message;
1280*635a8641SAndroid Build Coastguard Worker std::unique_ptr<TraceEvent> filtered_trace_event;
1281*635a8641SAndroid Build Coastguard Worker bool disabled_by_filters = false;
1282*635a8641SAndroid Build Coastguard Worker if (*category_group_enabled & TraceCategory::ENABLED_FOR_FILTERING) {
1283*635a8641SAndroid Build Coastguard Worker std::unique_ptr<TraceEvent> new_trace_event(new TraceEvent);
1284*635a8641SAndroid Build Coastguard Worker new_trace_event->Initialize(thread_id, offset_event_timestamp, thread_now,
1285*635a8641SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id,
1286*635a8641SAndroid Build Coastguard Worker bind_id, num_args, arg_names, arg_types,
1287*635a8641SAndroid Build Coastguard Worker arg_values, convertable_values, flags);
1288*635a8641SAndroid Build Coastguard Worker
1289*635a8641SAndroid Build Coastguard Worker disabled_by_filters = true;
1290*635a8641SAndroid Build Coastguard Worker ForEachCategoryFilter(
1291*635a8641SAndroid Build Coastguard Worker category_group_enabled, [&new_trace_event, &disabled_by_filters](
1292*635a8641SAndroid Build Coastguard Worker TraceEventFilter* trace_event_filter) {
1293*635a8641SAndroid Build Coastguard Worker if (trace_event_filter->FilterTraceEvent(*new_trace_event))
1294*635a8641SAndroid Build Coastguard Worker disabled_by_filters = false;
1295*635a8641SAndroid Build Coastguard Worker });
1296*635a8641SAndroid Build Coastguard Worker if (!disabled_by_filters)
1297*635a8641SAndroid Build Coastguard Worker filtered_trace_event = std::move(new_trace_event);
1298*635a8641SAndroid Build Coastguard Worker }
1299*635a8641SAndroid Build Coastguard Worker
1300*635a8641SAndroid Build Coastguard Worker // If enabled for recording, the event should be added only if one of the
1301*635a8641SAndroid Build Coastguard Worker // filters indicates or category is not enabled for filtering.
1302*635a8641SAndroid Build Coastguard Worker if ((*category_group_enabled & TraceCategory::ENABLED_FOR_RECORDING) &&
1303*635a8641SAndroid Build Coastguard Worker !disabled_by_filters) {
1304*635a8641SAndroid Build Coastguard Worker OptionalAutoLock lock(&lock_);
1305*635a8641SAndroid Build Coastguard Worker
1306*635a8641SAndroid Build Coastguard Worker TraceEvent* trace_event = nullptr;
1307*635a8641SAndroid Build Coastguard Worker if (thread_local_event_buffer) {
1308*635a8641SAndroid Build Coastguard Worker trace_event = thread_local_event_buffer->AddTraceEvent(&handle);
1309*635a8641SAndroid Build Coastguard Worker } else {
1310*635a8641SAndroid Build Coastguard Worker lock.EnsureAcquired();
1311*635a8641SAndroid Build Coastguard Worker trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true);
1312*635a8641SAndroid Build Coastguard Worker }
1313*635a8641SAndroid Build Coastguard Worker
1314*635a8641SAndroid Build Coastguard Worker if (trace_event) {
1315*635a8641SAndroid Build Coastguard Worker if (filtered_trace_event) {
1316*635a8641SAndroid Build Coastguard Worker trace_event->MoveFrom(std::move(filtered_trace_event));
1317*635a8641SAndroid Build Coastguard Worker } else {
1318*635a8641SAndroid Build Coastguard Worker trace_event->Initialize(thread_id, offset_event_timestamp, thread_now,
1319*635a8641SAndroid Build Coastguard Worker phase, category_group_enabled, name, scope, id,
1320*635a8641SAndroid Build Coastguard Worker bind_id, num_args, arg_names, arg_types,
1321*635a8641SAndroid Build Coastguard Worker arg_values, convertable_values, flags);
1322*635a8641SAndroid Build Coastguard Worker }
1323*635a8641SAndroid Build Coastguard Worker
1324*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
1325*635a8641SAndroid Build Coastguard Worker trace_event->SendToATrace();
1326*635a8641SAndroid Build Coastguard Worker #endif
1327*635a8641SAndroid Build Coastguard Worker }
1328*635a8641SAndroid Build Coastguard Worker
1329*635a8641SAndroid Build Coastguard Worker if (trace_options() & kInternalEchoToConsole) {
1330*635a8641SAndroid Build Coastguard Worker console_message = EventToConsoleMessage(
1331*635a8641SAndroid Build Coastguard Worker phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase,
1332*635a8641SAndroid Build Coastguard Worker timestamp, trace_event);
1333*635a8641SAndroid Build Coastguard Worker }
1334*635a8641SAndroid Build Coastguard Worker }
1335*635a8641SAndroid Build Coastguard Worker
1336*635a8641SAndroid Build Coastguard Worker if (!console_message.empty())
1337*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << console_message;
1338*635a8641SAndroid Build Coastguard Worker
1339*635a8641SAndroid Build Coastguard Worker return handle;
1340*635a8641SAndroid Build Coastguard Worker }
1341*635a8641SAndroid Build Coastguard Worker
AddMetadataEvent(const unsigned char * category_group_enabled,const char * name,int num_args,const char * const * arg_names,const unsigned char * arg_types,const unsigned long long * arg_values,std::unique_ptr<ConvertableToTraceFormat> * convertable_values,unsigned int flags)1342*635a8641SAndroid Build Coastguard Worker void TraceLog::AddMetadataEvent(
1343*635a8641SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1344*635a8641SAndroid Build Coastguard Worker const char* name,
1345*635a8641SAndroid Build Coastguard Worker int num_args,
1346*635a8641SAndroid Build Coastguard Worker const char* const* arg_names,
1347*635a8641SAndroid Build Coastguard Worker const unsigned char* arg_types,
1348*635a8641SAndroid Build Coastguard Worker const unsigned long long* arg_values,
1349*635a8641SAndroid Build Coastguard Worker std::unique_ptr<ConvertableToTraceFormat>* convertable_values,
1350*635a8641SAndroid Build Coastguard Worker unsigned int flags) {
1351*635a8641SAndroid Build Coastguard Worker HEAP_PROFILER_SCOPED_IGNORE;
1352*635a8641SAndroid Build Coastguard Worker std::unique_ptr<TraceEvent> trace_event(new TraceEvent);
1353*635a8641SAndroid Build Coastguard Worker int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1354*635a8641SAndroid Build Coastguard Worker ThreadTicks thread_now = ThreadNow();
1355*635a8641SAndroid Build Coastguard Worker TimeTicks now = OffsetNow();
1356*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1357*635a8641SAndroid Build Coastguard Worker trace_event->Initialize(
1358*635a8641SAndroid Build Coastguard Worker thread_id, now, thread_now, TRACE_EVENT_PHASE_METADATA,
1359*635a8641SAndroid Build Coastguard Worker category_group_enabled, name,
1360*635a8641SAndroid Build Coastguard Worker trace_event_internal::kGlobalScope, // scope
1361*635a8641SAndroid Build Coastguard Worker trace_event_internal::kNoId, // id
1362*635a8641SAndroid Build Coastguard Worker trace_event_internal::kNoId, // bind_id
1363*635a8641SAndroid Build Coastguard Worker num_args, arg_names, arg_types, arg_values, convertable_values, flags);
1364*635a8641SAndroid Build Coastguard Worker metadata_events_.push_back(std::move(trace_event));
1365*635a8641SAndroid Build Coastguard Worker }
1366*635a8641SAndroid Build Coastguard Worker
1367*635a8641SAndroid Build Coastguard Worker // May be called when a COMPELETE event ends and the unfinished event has been
1368*635a8641SAndroid Build Coastguard Worker // recycled (phase == TRACE_EVENT_PHASE_END and trace_event == NULL).
EventToConsoleMessage(unsigned char phase,const TimeTicks & timestamp,TraceEvent * trace_event)1369*635a8641SAndroid Build Coastguard Worker std::string TraceLog::EventToConsoleMessage(unsigned char phase,
1370*635a8641SAndroid Build Coastguard Worker const TimeTicks& timestamp,
1371*635a8641SAndroid Build Coastguard Worker TraceEvent* trace_event) {
1372*635a8641SAndroid Build Coastguard Worker HEAP_PROFILER_SCOPED_IGNORE;
1373*635a8641SAndroid Build Coastguard Worker AutoLock thread_info_lock(thread_info_lock_);
1374*635a8641SAndroid Build Coastguard Worker
1375*635a8641SAndroid Build Coastguard Worker // The caller should translate TRACE_EVENT_PHASE_COMPLETE to
1376*635a8641SAndroid Build Coastguard Worker // TRACE_EVENT_PHASE_BEGIN or TRACE_EVENT_END.
1377*635a8641SAndroid Build Coastguard Worker DCHECK(phase != TRACE_EVENT_PHASE_COMPLETE);
1378*635a8641SAndroid Build Coastguard Worker
1379*635a8641SAndroid Build Coastguard Worker TimeDelta duration;
1380*635a8641SAndroid Build Coastguard Worker int thread_id =
1381*635a8641SAndroid Build Coastguard Worker trace_event ? trace_event->thread_id() : PlatformThread::CurrentId();
1382*635a8641SAndroid Build Coastguard Worker if (phase == TRACE_EVENT_PHASE_END) {
1383*635a8641SAndroid Build Coastguard Worker duration = timestamp - thread_event_start_times_[thread_id].top();
1384*635a8641SAndroid Build Coastguard Worker thread_event_start_times_[thread_id].pop();
1385*635a8641SAndroid Build Coastguard Worker }
1386*635a8641SAndroid Build Coastguard Worker
1387*635a8641SAndroid Build Coastguard Worker std::string thread_name = thread_names_[thread_id];
1388*635a8641SAndroid Build Coastguard Worker if (thread_colors_.find(thread_name) == thread_colors_.end()) {
1389*635a8641SAndroid Build Coastguard Worker size_t next_color = (thread_colors_.size() % 6) + 1;
1390*635a8641SAndroid Build Coastguard Worker thread_colors_[thread_name] = next_color;
1391*635a8641SAndroid Build Coastguard Worker }
1392*635a8641SAndroid Build Coastguard Worker
1393*635a8641SAndroid Build Coastguard Worker std::ostringstream log;
1394*635a8641SAndroid Build Coastguard Worker log << base::StringPrintf("%s: \x1b[0;3%dm", thread_name.c_str(),
1395*635a8641SAndroid Build Coastguard Worker thread_colors_[thread_name]);
1396*635a8641SAndroid Build Coastguard Worker
1397*635a8641SAndroid Build Coastguard Worker size_t depth = 0;
1398*635a8641SAndroid Build Coastguard Worker auto it = thread_event_start_times_.find(thread_id);
1399*635a8641SAndroid Build Coastguard Worker if (it != thread_event_start_times_.end())
1400*635a8641SAndroid Build Coastguard Worker depth = it->second.size();
1401*635a8641SAndroid Build Coastguard Worker
1402*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < depth; ++i)
1403*635a8641SAndroid Build Coastguard Worker log << "| ";
1404*635a8641SAndroid Build Coastguard Worker
1405*635a8641SAndroid Build Coastguard Worker if (trace_event)
1406*635a8641SAndroid Build Coastguard Worker trace_event->AppendPrettyPrinted(&log);
1407*635a8641SAndroid Build Coastguard Worker if (phase == TRACE_EVENT_PHASE_END)
1408*635a8641SAndroid Build Coastguard Worker log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF());
1409*635a8641SAndroid Build Coastguard Worker
1410*635a8641SAndroid Build Coastguard Worker log << "\x1b[0;m";
1411*635a8641SAndroid Build Coastguard Worker
1412*635a8641SAndroid Build Coastguard Worker if (phase == TRACE_EVENT_PHASE_BEGIN)
1413*635a8641SAndroid Build Coastguard Worker thread_event_start_times_[thread_id].push(timestamp);
1414*635a8641SAndroid Build Coastguard Worker
1415*635a8641SAndroid Build Coastguard Worker return log.str();
1416*635a8641SAndroid Build Coastguard Worker }
1417*635a8641SAndroid Build Coastguard Worker
EndFilteredEvent(const unsigned char * category_group_enabled,const char * name,TraceEventHandle handle)1418*635a8641SAndroid Build Coastguard Worker void TraceLog::EndFilteredEvent(const unsigned char* category_group_enabled,
1419*635a8641SAndroid Build Coastguard Worker const char* name,
1420*635a8641SAndroid Build Coastguard Worker TraceEventHandle handle) {
1421*635a8641SAndroid Build Coastguard Worker const char* category_name = GetCategoryGroupName(category_group_enabled);
1422*635a8641SAndroid Build Coastguard Worker ForEachCategoryFilter(
1423*635a8641SAndroid Build Coastguard Worker category_group_enabled,
1424*635a8641SAndroid Build Coastguard Worker [name, category_name](TraceEventFilter* trace_event_filter) {
1425*635a8641SAndroid Build Coastguard Worker trace_event_filter->EndEvent(category_name, name);
1426*635a8641SAndroid Build Coastguard Worker });
1427*635a8641SAndroid Build Coastguard Worker }
1428*635a8641SAndroid Build Coastguard Worker
UpdateTraceEventDuration(const unsigned char * category_group_enabled,const char * name,TraceEventHandle handle)1429*635a8641SAndroid Build Coastguard Worker void TraceLog::UpdateTraceEventDuration(
1430*635a8641SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1431*635a8641SAndroid Build Coastguard Worker const char* name,
1432*635a8641SAndroid Build Coastguard Worker TraceEventHandle handle) {
1433*635a8641SAndroid Build Coastguard Worker char category_group_enabled_local = *category_group_enabled;
1434*635a8641SAndroid Build Coastguard Worker if (!category_group_enabled_local)
1435*635a8641SAndroid Build Coastguard Worker return;
1436*635a8641SAndroid Build Coastguard Worker
1437*635a8641SAndroid Build Coastguard Worker UpdateTraceEventDurationExplicit(category_group_enabled, name, handle,
1438*635a8641SAndroid Build Coastguard Worker OffsetNow(), ThreadNow());
1439*635a8641SAndroid Build Coastguard Worker }
1440*635a8641SAndroid Build Coastguard Worker
UpdateTraceEventDurationExplicit(const unsigned char * category_group_enabled,const char * name,TraceEventHandle handle,const TimeTicks & now,const ThreadTicks & thread_now)1441*635a8641SAndroid Build Coastguard Worker void TraceLog::UpdateTraceEventDurationExplicit(
1442*635a8641SAndroid Build Coastguard Worker const unsigned char* category_group_enabled,
1443*635a8641SAndroid Build Coastguard Worker const char* name,
1444*635a8641SAndroid Build Coastguard Worker TraceEventHandle handle,
1445*635a8641SAndroid Build Coastguard Worker const TimeTicks& now,
1446*635a8641SAndroid Build Coastguard Worker const ThreadTicks& thread_now) {
1447*635a8641SAndroid Build Coastguard Worker char category_group_enabled_local = *category_group_enabled;
1448*635a8641SAndroid Build Coastguard Worker if (!category_group_enabled_local)
1449*635a8641SAndroid Build Coastguard Worker return;
1450*635a8641SAndroid Build Coastguard Worker
1451*635a8641SAndroid Build Coastguard Worker // Avoid re-entrance of AddTraceEvent. This may happen in GPU process when
1452*635a8641SAndroid Build Coastguard Worker // ECHO_TO_CONSOLE is enabled: AddTraceEvent -> LOG(ERROR) ->
1453*635a8641SAndroid Build Coastguard Worker // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ...
1454*635a8641SAndroid Build Coastguard Worker if (thread_is_in_trace_event_.Get())
1455*635a8641SAndroid Build Coastguard Worker return;
1456*635a8641SAndroid Build Coastguard Worker AutoThreadLocalBoolean thread_is_in_trace_event(&thread_is_in_trace_event_);
1457*635a8641SAndroid Build Coastguard Worker
1458*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
1459*635a8641SAndroid Build Coastguard Worker // Generate an ETW event that marks the end of a complete event.
1460*635a8641SAndroid Build Coastguard Worker if (category_group_enabled_local & TraceCategory::ENABLED_FOR_ETW_EXPORT)
1461*635a8641SAndroid Build Coastguard Worker TraceEventETWExport::AddCompleteEndEvent(name);
1462*635a8641SAndroid Build Coastguard Worker #endif // OS_WIN
1463*635a8641SAndroid Build Coastguard Worker
1464*635a8641SAndroid Build Coastguard Worker std::string console_message;
1465*635a8641SAndroid Build Coastguard Worker if (category_group_enabled_local & TraceCategory::ENABLED_FOR_RECORDING) {
1466*635a8641SAndroid Build Coastguard Worker AddTraceEventOverrideCallback trace_event_override =
1467*635a8641SAndroid Build Coastguard Worker reinterpret_cast<AddTraceEventOverrideCallback>(
1468*635a8641SAndroid Build Coastguard Worker subtle::NoBarrier_Load(&trace_event_override_));
1469*635a8641SAndroid Build Coastguard Worker
1470*635a8641SAndroid Build Coastguard Worker // If we send events off to an override instead of the TraceBuffer,
1471*635a8641SAndroid Build Coastguard Worker // we don't have way of updating the prior event so we'll emit a
1472*635a8641SAndroid Build Coastguard Worker // separate _END event instead.
1473*635a8641SAndroid Build Coastguard Worker if (trace_event_override) {
1474*635a8641SAndroid Build Coastguard Worker TraceEvent new_trace_event;
1475*635a8641SAndroid Build Coastguard Worker new_trace_event.Initialize(
1476*635a8641SAndroid Build Coastguard Worker static_cast<int>(base::PlatformThread::CurrentId()), now, thread_now,
1477*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_PHASE_END, category_group_enabled, name,
1478*635a8641SAndroid Build Coastguard Worker trace_event_internal::kGlobalScope,
1479*635a8641SAndroid Build Coastguard Worker trace_event_internal::kNoId /* id */,
1480*635a8641SAndroid Build Coastguard Worker trace_event_internal::kNoId /* bind_id */, 0, nullptr, nullptr,
1481*635a8641SAndroid Build Coastguard Worker nullptr, nullptr, TRACE_EVENT_FLAG_NONE);
1482*635a8641SAndroid Build Coastguard Worker trace_event_override(new_trace_event);
1483*635a8641SAndroid Build Coastguard Worker return;
1484*635a8641SAndroid Build Coastguard Worker }
1485*635a8641SAndroid Build Coastguard Worker
1486*635a8641SAndroid Build Coastguard Worker OptionalAutoLock lock(&lock_);
1487*635a8641SAndroid Build Coastguard Worker
1488*635a8641SAndroid Build Coastguard Worker TraceEvent* trace_event = GetEventByHandleInternal(handle, &lock);
1489*635a8641SAndroid Build Coastguard Worker if (trace_event) {
1490*635a8641SAndroid Build Coastguard Worker DCHECK(trace_event->phase() == TRACE_EVENT_PHASE_COMPLETE);
1491*635a8641SAndroid Build Coastguard Worker // TEMP(oysteine) to debug crbug.com/638744
1492*635a8641SAndroid Build Coastguard Worker if (trace_event->duration().ToInternalValue() != -1) {
1493*635a8641SAndroid Build Coastguard Worker DVLOG(1) << "TraceHandle: chunk_seq " << handle.chunk_seq
1494*635a8641SAndroid Build Coastguard Worker << ", chunk_index " << handle.chunk_index << ", event_index "
1495*635a8641SAndroid Build Coastguard Worker << handle.event_index;
1496*635a8641SAndroid Build Coastguard Worker
1497*635a8641SAndroid Build Coastguard Worker std::string serialized_event;
1498*635a8641SAndroid Build Coastguard Worker trace_event->AppendAsJSON(&serialized_event, ArgumentFilterPredicate());
1499*635a8641SAndroid Build Coastguard Worker DVLOG(1) << "TraceEvent: " << serialized_event;
1500*635a8641SAndroid Build Coastguard Worker lock_.AssertAcquired();
1501*635a8641SAndroid Build Coastguard Worker }
1502*635a8641SAndroid Build Coastguard Worker
1503*635a8641SAndroid Build Coastguard Worker trace_event->UpdateDuration(now, thread_now);
1504*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
1505*635a8641SAndroid Build Coastguard Worker trace_event->SendToATrace();
1506*635a8641SAndroid Build Coastguard Worker #endif
1507*635a8641SAndroid Build Coastguard Worker }
1508*635a8641SAndroid Build Coastguard Worker
1509*635a8641SAndroid Build Coastguard Worker if (trace_options() & kInternalEchoToConsole) {
1510*635a8641SAndroid Build Coastguard Worker console_message =
1511*635a8641SAndroid Build Coastguard Worker EventToConsoleMessage(TRACE_EVENT_PHASE_END, now, trace_event);
1512*635a8641SAndroid Build Coastguard Worker }
1513*635a8641SAndroid Build Coastguard Worker }
1514*635a8641SAndroid Build Coastguard Worker
1515*635a8641SAndroid Build Coastguard Worker if (!console_message.empty())
1516*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << console_message;
1517*635a8641SAndroid Build Coastguard Worker
1518*635a8641SAndroid Build Coastguard Worker if (category_group_enabled_local & TraceCategory::ENABLED_FOR_FILTERING)
1519*635a8641SAndroid Build Coastguard Worker EndFilteredEvent(category_group_enabled, name, handle);
1520*635a8641SAndroid Build Coastguard Worker }
1521*635a8641SAndroid Build Coastguard Worker
MangleEventId(uint64_t id)1522*635a8641SAndroid Build Coastguard Worker uint64_t TraceLog::MangleEventId(uint64_t id) {
1523*635a8641SAndroid Build Coastguard Worker return id ^ process_id_hash_;
1524*635a8641SAndroid Build Coastguard Worker }
1525*635a8641SAndroid Build Coastguard Worker
AddMetadataEventsWhileLocked()1526*635a8641SAndroid Build Coastguard Worker void TraceLog::AddMetadataEventsWhileLocked() {
1527*635a8641SAndroid Build Coastguard Worker lock_.AssertAcquired();
1528*635a8641SAndroid Build Coastguard Worker
1529*635a8641SAndroid Build Coastguard Worker // Move metadata added by |AddMetadataEvent| into the trace log.
1530*635a8641SAndroid Build Coastguard Worker while (!metadata_events_.empty()) {
1531*635a8641SAndroid Build Coastguard Worker TraceEvent* event = AddEventToThreadSharedChunkWhileLocked(nullptr, false);
1532*635a8641SAndroid Build Coastguard Worker event->MoveFrom(std::move(metadata_events_.back()));
1533*635a8641SAndroid Build Coastguard Worker metadata_events_.pop_back();
1534*635a8641SAndroid Build Coastguard Worker }
1535*635a8641SAndroid Build Coastguard Worker
1536*635a8641SAndroid Build Coastguard Worker #if !defined(OS_NACL) // NaCl shouldn't expose the process id.
1537*635a8641SAndroid Build Coastguard Worker InitializeMetadataEvent(
1538*635a8641SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false), 0, "num_cpus",
1539*635a8641SAndroid Build Coastguard Worker "number", base::SysInfo::NumberOfProcessors());
1540*635a8641SAndroid Build Coastguard Worker #endif
1541*635a8641SAndroid Build Coastguard Worker
1542*635a8641SAndroid Build Coastguard Worker int current_thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1543*635a8641SAndroid Build Coastguard Worker if (process_sort_index_ != 0) {
1544*635a8641SAndroid Build Coastguard Worker InitializeMetadataEvent(
1545*635a8641SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false),
1546*635a8641SAndroid Build Coastguard Worker current_thread_id, "process_sort_index", "sort_index",
1547*635a8641SAndroid Build Coastguard Worker process_sort_index_);
1548*635a8641SAndroid Build Coastguard Worker }
1549*635a8641SAndroid Build Coastguard Worker
1550*635a8641SAndroid Build Coastguard Worker if (!process_name_.empty()) {
1551*635a8641SAndroid Build Coastguard Worker InitializeMetadataEvent(
1552*635a8641SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false),
1553*635a8641SAndroid Build Coastguard Worker current_thread_id, "process_name", "name", process_name_);
1554*635a8641SAndroid Build Coastguard Worker }
1555*635a8641SAndroid Build Coastguard Worker
1556*635a8641SAndroid Build Coastguard Worker TimeDelta process_uptime = TRACE_TIME_NOW() - process_creation_time_;
1557*635a8641SAndroid Build Coastguard Worker InitializeMetadataEvent(
1558*635a8641SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false), current_thread_id,
1559*635a8641SAndroid Build Coastguard Worker "process_uptime_seconds", "uptime", process_uptime.InSeconds());
1560*635a8641SAndroid Build Coastguard Worker
1561*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
1562*635a8641SAndroid Build Coastguard Worker InitializeMetadataEvent(
1563*635a8641SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false), current_thread_id,
1564*635a8641SAndroid Build Coastguard Worker "chrome_library_address", "start_address",
1565*635a8641SAndroid Build Coastguard Worker base::StringPrintf("%p", &__executable_start));
1566*635a8641SAndroid Build Coastguard Worker #endif
1567*635a8641SAndroid Build Coastguard Worker
1568*635a8641SAndroid Build Coastguard Worker if (!process_labels_.empty()) {
1569*635a8641SAndroid Build Coastguard Worker std::vector<base::StringPiece> labels;
1570*635a8641SAndroid Build Coastguard Worker for (const auto& it : process_labels_)
1571*635a8641SAndroid Build Coastguard Worker labels.push_back(it.second);
1572*635a8641SAndroid Build Coastguard Worker InitializeMetadataEvent(
1573*635a8641SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false),
1574*635a8641SAndroid Build Coastguard Worker current_thread_id, "process_labels", "labels",
1575*635a8641SAndroid Build Coastguard Worker base::JoinString(labels, ","));
1576*635a8641SAndroid Build Coastguard Worker }
1577*635a8641SAndroid Build Coastguard Worker
1578*635a8641SAndroid Build Coastguard Worker // Thread sort indices.
1579*635a8641SAndroid Build Coastguard Worker for (const auto& it : thread_sort_indices_) {
1580*635a8641SAndroid Build Coastguard Worker if (it.second == 0)
1581*635a8641SAndroid Build Coastguard Worker continue;
1582*635a8641SAndroid Build Coastguard Worker InitializeMetadataEvent(
1583*635a8641SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false), it.first,
1584*635a8641SAndroid Build Coastguard Worker "thread_sort_index", "sort_index", it.second);
1585*635a8641SAndroid Build Coastguard Worker }
1586*635a8641SAndroid Build Coastguard Worker
1587*635a8641SAndroid Build Coastguard Worker // Thread names.
1588*635a8641SAndroid Build Coastguard Worker AutoLock thread_info_lock(thread_info_lock_);
1589*635a8641SAndroid Build Coastguard Worker for (const auto& it : thread_names_) {
1590*635a8641SAndroid Build Coastguard Worker if (it.second.empty())
1591*635a8641SAndroid Build Coastguard Worker continue;
1592*635a8641SAndroid Build Coastguard Worker InitializeMetadataEvent(
1593*635a8641SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false), it.first,
1594*635a8641SAndroid Build Coastguard Worker "thread_name", "name", it.second);
1595*635a8641SAndroid Build Coastguard Worker }
1596*635a8641SAndroid Build Coastguard Worker
1597*635a8641SAndroid Build Coastguard Worker // If buffer is full, add a metadata record to report this.
1598*635a8641SAndroid Build Coastguard Worker if (!buffer_limit_reached_timestamp_.is_null()) {
1599*635a8641SAndroid Build Coastguard Worker InitializeMetadataEvent(
1600*635a8641SAndroid Build Coastguard Worker AddEventToThreadSharedChunkWhileLocked(nullptr, false),
1601*635a8641SAndroid Build Coastguard Worker current_thread_id, "trace_buffer_overflowed", "overflowed_at_ts",
1602*635a8641SAndroid Build Coastguard Worker buffer_limit_reached_timestamp_);
1603*635a8641SAndroid Build Coastguard Worker }
1604*635a8641SAndroid Build Coastguard Worker }
1605*635a8641SAndroid Build Coastguard Worker
GetEventByHandle(TraceEventHandle handle)1606*635a8641SAndroid Build Coastguard Worker TraceEvent* TraceLog::GetEventByHandle(TraceEventHandle handle) {
1607*635a8641SAndroid Build Coastguard Worker return GetEventByHandleInternal(handle, nullptr);
1608*635a8641SAndroid Build Coastguard Worker }
1609*635a8641SAndroid Build Coastguard Worker
GetEventByHandleInternal(TraceEventHandle handle,OptionalAutoLock * lock)1610*635a8641SAndroid Build Coastguard Worker TraceEvent* TraceLog::GetEventByHandleInternal(TraceEventHandle handle,
1611*635a8641SAndroid Build Coastguard Worker OptionalAutoLock* lock) {
1612*635a8641SAndroid Build Coastguard Worker if (!handle.chunk_seq)
1613*635a8641SAndroid Build Coastguard Worker return nullptr;
1614*635a8641SAndroid Build Coastguard Worker
1615*635a8641SAndroid Build Coastguard Worker DCHECK(handle.chunk_seq);
1616*635a8641SAndroid Build Coastguard Worker DCHECK(handle.chunk_index <= TraceBufferChunk::kMaxChunkIndex);
1617*635a8641SAndroid Build Coastguard Worker DCHECK(handle.event_index <= TraceBufferChunk::kTraceBufferChunkSize - 1);
1618*635a8641SAndroid Build Coastguard Worker
1619*635a8641SAndroid Build Coastguard Worker if (thread_local_event_buffer_.Get()) {
1620*635a8641SAndroid Build Coastguard Worker TraceEvent* trace_event =
1621*635a8641SAndroid Build Coastguard Worker thread_local_event_buffer_.Get()->GetEventByHandle(handle);
1622*635a8641SAndroid Build Coastguard Worker if (trace_event)
1623*635a8641SAndroid Build Coastguard Worker return trace_event;
1624*635a8641SAndroid Build Coastguard Worker }
1625*635a8641SAndroid Build Coastguard Worker
1626*635a8641SAndroid Build Coastguard Worker // The event has been out-of-control of the thread local buffer.
1627*635a8641SAndroid Build Coastguard Worker // Try to get the event from the main buffer with a lock.
1628*635a8641SAndroid Build Coastguard Worker if (lock)
1629*635a8641SAndroid Build Coastguard Worker lock->EnsureAcquired();
1630*635a8641SAndroid Build Coastguard Worker
1631*635a8641SAndroid Build Coastguard Worker if (thread_shared_chunk_ &&
1632*635a8641SAndroid Build Coastguard Worker handle.chunk_index == thread_shared_chunk_index_) {
1633*635a8641SAndroid Build Coastguard Worker return handle.chunk_seq == thread_shared_chunk_->seq()
1634*635a8641SAndroid Build Coastguard Worker ? thread_shared_chunk_->GetEventAt(handle.event_index)
1635*635a8641SAndroid Build Coastguard Worker : nullptr;
1636*635a8641SAndroid Build Coastguard Worker }
1637*635a8641SAndroid Build Coastguard Worker
1638*635a8641SAndroid Build Coastguard Worker return logged_events_->GetEventByHandle(handle);
1639*635a8641SAndroid Build Coastguard Worker }
1640*635a8641SAndroid Build Coastguard Worker
SetProcessID(int process_id)1641*635a8641SAndroid Build Coastguard Worker void TraceLog::SetProcessID(int process_id) {
1642*635a8641SAndroid Build Coastguard Worker process_id_ = process_id;
1643*635a8641SAndroid Build Coastguard Worker // Create a FNV hash from the process ID for XORing.
1644*635a8641SAndroid Build Coastguard Worker // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details.
1645*635a8641SAndroid Build Coastguard Worker const unsigned long long kOffsetBasis = 14695981039346656037ull;
1646*635a8641SAndroid Build Coastguard Worker const unsigned long long kFnvPrime = 1099511628211ull;
1647*635a8641SAndroid Build Coastguard Worker const unsigned long long pid = static_cast<unsigned long long>(process_id_);
1648*635a8641SAndroid Build Coastguard Worker process_id_hash_ = (kOffsetBasis ^ pid) * kFnvPrime;
1649*635a8641SAndroid Build Coastguard Worker }
1650*635a8641SAndroid Build Coastguard Worker
SetProcessSortIndex(int sort_index)1651*635a8641SAndroid Build Coastguard Worker void TraceLog::SetProcessSortIndex(int sort_index) {
1652*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1653*635a8641SAndroid Build Coastguard Worker process_sort_index_ = sort_index;
1654*635a8641SAndroid Build Coastguard Worker }
1655*635a8641SAndroid Build Coastguard Worker
UpdateProcessLabel(int label_id,const std::string & current_label)1656*635a8641SAndroid Build Coastguard Worker void TraceLog::UpdateProcessLabel(int label_id,
1657*635a8641SAndroid Build Coastguard Worker const std::string& current_label) {
1658*635a8641SAndroid Build Coastguard Worker if (!current_label.length())
1659*635a8641SAndroid Build Coastguard Worker return RemoveProcessLabel(label_id);
1660*635a8641SAndroid Build Coastguard Worker
1661*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1662*635a8641SAndroid Build Coastguard Worker process_labels_[label_id] = current_label;
1663*635a8641SAndroid Build Coastguard Worker }
1664*635a8641SAndroid Build Coastguard Worker
RemoveProcessLabel(int label_id)1665*635a8641SAndroid Build Coastguard Worker void TraceLog::RemoveProcessLabel(int label_id) {
1666*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1667*635a8641SAndroid Build Coastguard Worker process_labels_.erase(label_id);
1668*635a8641SAndroid Build Coastguard Worker }
1669*635a8641SAndroid Build Coastguard Worker
SetThreadSortIndex(PlatformThreadId thread_id,int sort_index)1670*635a8641SAndroid Build Coastguard Worker void TraceLog::SetThreadSortIndex(PlatformThreadId thread_id, int sort_index) {
1671*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1672*635a8641SAndroid Build Coastguard Worker thread_sort_indices_[static_cast<int>(thread_id)] = sort_index;
1673*635a8641SAndroid Build Coastguard Worker }
1674*635a8641SAndroid Build Coastguard Worker
SetTimeOffset(TimeDelta offset)1675*635a8641SAndroid Build Coastguard Worker void TraceLog::SetTimeOffset(TimeDelta offset) {
1676*635a8641SAndroid Build Coastguard Worker time_offset_ = offset;
1677*635a8641SAndroid Build Coastguard Worker }
1678*635a8641SAndroid Build Coastguard Worker
GetObserverCountForTest() const1679*635a8641SAndroid Build Coastguard Worker size_t TraceLog::GetObserverCountForTest() const {
1680*635a8641SAndroid Build Coastguard Worker return enabled_state_observer_list_.size();
1681*635a8641SAndroid Build Coastguard Worker }
1682*635a8641SAndroid Build Coastguard Worker
SetCurrentThreadBlocksMessageLoop()1683*635a8641SAndroid Build Coastguard Worker void TraceLog::SetCurrentThreadBlocksMessageLoop() {
1684*635a8641SAndroid Build Coastguard Worker thread_blocks_message_loop_.Set(true);
1685*635a8641SAndroid Build Coastguard Worker // This will flush the thread local buffer.
1686*635a8641SAndroid Build Coastguard Worker delete thread_local_event_buffer_.Get();
1687*635a8641SAndroid Build Coastguard Worker }
1688*635a8641SAndroid Build Coastguard Worker
CreateTraceBuffer()1689*635a8641SAndroid Build Coastguard Worker TraceBuffer* TraceLog::CreateTraceBuffer() {
1690*635a8641SAndroid Build Coastguard Worker HEAP_PROFILER_SCOPED_IGNORE;
1691*635a8641SAndroid Build Coastguard Worker InternalTraceOptions options = trace_options();
1692*635a8641SAndroid Build Coastguard Worker if (options & kInternalRecordContinuously) {
1693*635a8641SAndroid Build Coastguard Worker return TraceBuffer::CreateTraceBufferRingBuffer(
1694*635a8641SAndroid Build Coastguard Worker kTraceEventRingBufferChunks);
1695*635a8641SAndroid Build Coastguard Worker }
1696*635a8641SAndroid Build Coastguard Worker if (options & kInternalEchoToConsole) {
1697*635a8641SAndroid Build Coastguard Worker return TraceBuffer::CreateTraceBufferRingBuffer(
1698*635a8641SAndroid Build Coastguard Worker kEchoToConsoleTraceEventBufferChunks);
1699*635a8641SAndroid Build Coastguard Worker }
1700*635a8641SAndroid Build Coastguard Worker if (options & kInternalRecordAsMuchAsPossible) {
1701*635a8641SAndroid Build Coastguard Worker return TraceBuffer::CreateTraceBufferVectorOfSize(
1702*635a8641SAndroid Build Coastguard Worker kTraceEventVectorBigBufferChunks);
1703*635a8641SAndroid Build Coastguard Worker }
1704*635a8641SAndroid Build Coastguard Worker return TraceBuffer::CreateTraceBufferVectorOfSize(
1705*635a8641SAndroid Build Coastguard Worker kTraceEventVectorBufferChunks);
1706*635a8641SAndroid Build Coastguard Worker }
1707*635a8641SAndroid Build Coastguard Worker
1708*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
UpdateETWCategoryGroupEnabledFlags()1709*635a8641SAndroid Build Coastguard Worker void TraceLog::UpdateETWCategoryGroupEnabledFlags() {
1710*635a8641SAndroid Build Coastguard Worker // Go through each category and set/clear the ETW bit depending on whether the
1711*635a8641SAndroid Build Coastguard Worker // category is enabled.
1712*635a8641SAndroid Build Coastguard Worker for (TraceCategory& category : CategoryRegistry::GetAllCategories()) {
1713*635a8641SAndroid Build Coastguard Worker if (base::trace_event::TraceEventETWExport::IsCategoryGroupEnabled(
1714*635a8641SAndroid Build Coastguard Worker category.name())) {
1715*635a8641SAndroid Build Coastguard Worker category.set_state_flag(TraceCategory::ENABLED_FOR_ETW_EXPORT);
1716*635a8641SAndroid Build Coastguard Worker } else {
1717*635a8641SAndroid Build Coastguard Worker category.clear_state_flag(TraceCategory::ENABLED_FOR_ETW_EXPORT);
1718*635a8641SAndroid Build Coastguard Worker }
1719*635a8641SAndroid Build Coastguard Worker }
1720*635a8641SAndroid Build Coastguard Worker }
1721*635a8641SAndroid Build Coastguard Worker #endif // defined(OS_WIN)
1722*635a8641SAndroid Build Coastguard Worker
SetTraceBufferForTesting(std::unique_ptr<TraceBuffer> trace_buffer)1723*635a8641SAndroid Build Coastguard Worker void TraceLog::SetTraceBufferForTesting(
1724*635a8641SAndroid Build Coastguard Worker std::unique_ptr<TraceBuffer> trace_buffer) {
1725*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1726*635a8641SAndroid Build Coastguard Worker logged_events_ = std::move(trace_buffer);
1727*635a8641SAndroid Build Coastguard Worker }
1728*635a8641SAndroid Build Coastguard Worker
EstimateTraceMemoryOverhead(TraceEventMemoryOverhead * overhead)1729*635a8641SAndroid Build Coastguard Worker void ConvertableToTraceFormat::EstimateTraceMemoryOverhead(
1730*635a8641SAndroid Build Coastguard Worker TraceEventMemoryOverhead* overhead) {
1731*635a8641SAndroid Build Coastguard Worker overhead->Add(TraceEventMemoryOverhead::kConvertableToTraceFormat,
1732*635a8641SAndroid Build Coastguard Worker sizeof(*this));
1733*635a8641SAndroid Build Coastguard Worker }
1734*635a8641SAndroid Build Coastguard Worker
AddAsyncEnabledStateObserver(WeakPtr<AsyncEnabledStateObserver> listener)1735*635a8641SAndroid Build Coastguard Worker void TraceLog::AddAsyncEnabledStateObserver(
1736*635a8641SAndroid Build Coastguard Worker WeakPtr<AsyncEnabledStateObserver> listener) {
1737*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1738*635a8641SAndroid Build Coastguard Worker async_observers_.insert(
1739*635a8641SAndroid Build Coastguard Worker std::make_pair(listener.get(), RegisteredAsyncObserver(listener)));
1740*635a8641SAndroid Build Coastguard Worker }
1741*635a8641SAndroid Build Coastguard Worker
RemoveAsyncEnabledStateObserver(AsyncEnabledStateObserver * listener)1742*635a8641SAndroid Build Coastguard Worker void TraceLog::RemoveAsyncEnabledStateObserver(
1743*635a8641SAndroid Build Coastguard Worker AsyncEnabledStateObserver* listener) {
1744*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1745*635a8641SAndroid Build Coastguard Worker async_observers_.erase(listener);
1746*635a8641SAndroid Build Coastguard Worker }
1747*635a8641SAndroid Build Coastguard Worker
HasAsyncEnabledStateObserver(AsyncEnabledStateObserver * listener) const1748*635a8641SAndroid Build Coastguard Worker bool TraceLog::HasAsyncEnabledStateObserver(
1749*635a8641SAndroid Build Coastguard Worker AsyncEnabledStateObserver* listener) const {
1750*635a8641SAndroid Build Coastguard Worker AutoLock lock(lock_);
1751*635a8641SAndroid Build Coastguard Worker return ContainsKey(async_observers_, listener);
1752*635a8641SAndroid Build Coastguard Worker }
1753*635a8641SAndroid Build Coastguard Worker
1754*635a8641SAndroid Build Coastguard Worker } // namespace trace_event
1755*635a8641SAndroid Build Coastguard Worker } // namespace base
1756*635a8641SAndroid Build Coastguard Worker
1757*635a8641SAndroid Build Coastguard Worker namespace trace_event_internal {
1758*635a8641SAndroid Build Coastguard Worker
ScopedTraceBinaryEfficient(const char * category_group,const char * name)1759*635a8641SAndroid Build Coastguard Worker ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient(
1760*635a8641SAndroid Build Coastguard Worker const char* category_group,
1761*635a8641SAndroid Build Coastguard Worker const char* name) {
1762*635a8641SAndroid Build Coastguard Worker // The single atom works because for now the category_group can only be "gpu".
1763*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(strcmp(category_group, "gpu"), 0);
1764*635a8641SAndroid Build Coastguard Worker static TRACE_EVENT_API_ATOMIC_WORD atomic = 0;
1765*635a8641SAndroid Build Coastguard Worker INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES(
1766*635a8641SAndroid Build Coastguard Worker category_group, atomic, category_group_enabled_);
1767*635a8641SAndroid Build Coastguard Worker name_ = name;
1768*635a8641SAndroid Build Coastguard Worker if (*category_group_enabled_) {
1769*635a8641SAndroid Build Coastguard Worker event_handle_ =
1770*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
1771*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_PHASE_COMPLETE, category_group_enabled_, name,
1772*635a8641SAndroid Build Coastguard Worker trace_event_internal::kGlobalScope, // scope
1773*635a8641SAndroid Build Coastguard Worker trace_event_internal::kNoId, // id
1774*635a8641SAndroid Build Coastguard Worker static_cast<int>(base::PlatformThread::CurrentId()), // thread_id
1775*635a8641SAndroid Build Coastguard Worker TRACE_TIME_TICKS_NOW(), trace_event_internal::kZeroNumArgs, nullptr,
1776*635a8641SAndroid Build Coastguard Worker nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_NONE);
1777*635a8641SAndroid Build Coastguard Worker }
1778*635a8641SAndroid Build Coastguard Worker }
1779*635a8641SAndroid Build Coastguard Worker
~ScopedTraceBinaryEfficient()1780*635a8641SAndroid Build Coastguard Worker ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() {
1781*635a8641SAndroid Build Coastguard Worker if (*category_group_enabled_) {
1782*635a8641SAndroid Build Coastguard Worker TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, name_,
1783*635a8641SAndroid Build Coastguard Worker event_handle_);
1784*635a8641SAndroid Build Coastguard Worker }
1785*635a8641SAndroid Build Coastguard Worker }
1786*635a8641SAndroid Build Coastguard Worker
1787*635a8641SAndroid Build Coastguard Worker } // namespace trace_event_internal
1788