• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/trace_event/blame_context.h"
6 
7 #include "base/strings/stringprintf.h"
8 #include "base/trace_event/trace_event.h"
9 #include "base/trace_event/trace_event_argument.h"
10 
11 namespace base {
12 namespace trace_event {
13 
BlameContext(const char * category,const char * name,const char * type,const char * scope,int64_t id,const BlameContext * parent_context)14 BlameContext::BlameContext(const char* category,
15                            const char* name,
16                            const char* type,
17                            const char* scope,
18                            int64_t id,
19                            const BlameContext* parent_context)
20     : category_(category),
21       name_(name),
22       type_(type),
23       scope_(scope),
24       id_(id),
25       parent_scope_(parent_context ? parent_context->scope() : nullptr),
26       parent_id_(parent_context ? parent_context->id() : 0),
27       category_group_enabled_(nullptr),
28       weak_factory_(this) {
29   DCHECK(!parent_context || !std::strcmp(name_, parent_context->name()))
30       << "Parent blame context must have the same name";
31 }
32 
~BlameContext()33 BlameContext::~BlameContext() {
34   DCHECK(thread_checker_.CalledOnValidThread());
35   DCHECK(WasInitialized());
36   TRACE_EVENT_API_ADD_TRACE_EVENT(
37       TRACE_EVENT_PHASE_DELETE_OBJECT, category_group_enabled_, type_, scope_,
38       id_, 0, nullptr, nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID);
39   trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver(this);
40 }
41 
Enter()42 void BlameContext::Enter() {
43   DCHECK(WasInitialized());
44   TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_ENTER_CONTEXT,
45                                   category_group_enabled_, name_, scope_, id_,
46                                   0 /* num_args */, nullptr, nullptr, nullptr,
47                                   nullptr, TRACE_EVENT_FLAG_HAS_ID);
48 }
49 
Leave()50 void BlameContext::Leave() {
51   DCHECK(WasInitialized());
52   TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_LEAVE_CONTEXT,
53                                   category_group_enabled_, name_, scope_, id_,
54                                   0 /* num_args */, nullptr, nullptr, nullptr,
55                                   nullptr, TRACE_EVENT_FLAG_HAS_ID);
56 }
57 
TakeSnapshot()58 void BlameContext::TakeSnapshot() {
59   DCHECK(thread_checker_.CalledOnValidThread());
60   DCHECK(WasInitialized());
61   if (!*category_group_enabled_)
62     return;
63   std::unique_ptr<trace_event::TracedValue> snapshot(
64       new trace_event::TracedValue);
65   AsValueInto(snapshot.get());
66   static const char* const kArgName = "snapshot";
67   const int kNumArgs = 1;
68   unsigned char arg_types[1] = {TRACE_VALUE_TYPE_CONVERTABLE};
69   std::unique_ptr<trace_event::ConvertableToTraceFormat> arg_values[1] = {
70       std::move(snapshot)};
71   TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT,
72                                   category_group_enabled_, type_, scope_, id_,
73                                   kNumArgs, &kArgName, arg_types, nullptr,
74                                   arg_values, TRACE_EVENT_FLAG_HAS_ID);
75 }
76 
OnTraceLogEnabled()77 void BlameContext::OnTraceLogEnabled() {
78   DCHECK(WasInitialized());
79   TakeSnapshot();
80 }
81 
OnTraceLogDisabled()82 void BlameContext::OnTraceLogDisabled() {}
83 
AsValueInto(trace_event::TracedValue * state)84 void BlameContext::AsValueInto(trace_event::TracedValue* state) {
85   DCHECK(WasInitialized());
86   if (!parent_id_)
87     return;
88   state->BeginDictionary("parent");
89   state->SetString("id_ref", StringPrintf("0x%" PRIx64, parent_id_));
90   state->SetString("scope", parent_scope_);
91   state->EndDictionary();
92 }
93 
Initialize()94 void BlameContext::Initialize() {
95   DCHECK(thread_checker_.CalledOnValidThread());
96   category_group_enabled_ =
97       TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_);
98   TRACE_EVENT_API_ADD_TRACE_EVENT(
99       TRACE_EVENT_PHASE_CREATE_OBJECT, category_group_enabled_, type_, scope_,
100       id_, 0, nullptr, nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID);
101   trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver(
102       weak_factory_.GetWeakPtr());
103   TakeSnapshot();
104 }
105 
WasInitialized() const106 bool BlameContext::WasInitialized() const {
107   return category_group_enabled_ != nullptr;
108 }
109 
110 }  // namespace trace_event
111 }  // namespace base
112