summaryrefslogtreecommitdiffstats
path: root/base/trace_event/blame_context.cc
blob: 0bf78962d6ab559bba3aa657767b20bd652fe05c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/trace_event/blame_context.h"

#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"

namespace base {
namespace trace_event {

BlameContext::BlameContext(const char* category,
                           const char* name,
                           const char* type,
                           const char* scope,
                           int64_t id,
                           const BlameContext* parent_context)
    : category_(category),
      name_(name),
      type_(type),
      scope_(scope),
      id_(id),
      parent_scope_(parent_context ? parent_context->scope() : nullptr),
      parent_id_(parent_context ? parent_context->id() : 0),
      category_group_enabled_(nullptr) {
  DCHECK(!parent_context || !std::strcmp(name_, parent_context->name()))
      << "Parent blame context must have the same name";
}

BlameContext::~BlameContext() {
  DCHECK(WasInitialized());
  TRACE_EVENT_API_ADD_TRACE_EVENT(
      TRACE_EVENT_PHASE_DELETE_OBJECT, category_group_enabled_, type_, scope_,
      id_, 0, nullptr, nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID);
  trace_event::TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
}

void BlameContext::Enter() {
  DCHECK(WasInitialized());
  TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_ENTER_CONTEXT,
                                  category_group_enabled_, name_, scope_, id_,
                                  0 /* num_args */, nullptr, nullptr, nullptr,
                                  nullptr, TRACE_EVENT_FLAG_HAS_ID);
}

void BlameContext::Leave() {
  DCHECK(WasInitialized());
  TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_LEAVE_CONTEXT,
                                  category_group_enabled_, name_, scope_, id_,
                                  0 /* num_args */, nullptr, nullptr, nullptr,
                                  nullptr, TRACE_EVENT_FLAG_HAS_ID);
}

void BlameContext::TakeSnapshot() {
  DCHECK(WasInitialized());
  if (!*category_group_enabled_)
    return;
  scoped_ptr<trace_event::TracedValue> snapshot(new trace_event::TracedValue);
  AsValueInto(snapshot.get());
  static const char* kArgName = "snapshot";
  const int kNumArgs = 1;
  unsigned char arg_types[1] = {TRACE_VALUE_TYPE_CONVERTABLE};
  scoped_ptr<trace_event::ConvertableToTraceFormat> arg_values[1] = {
      std::move(snapshot)};
  TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT,
                                  category_group_enabled_, type_, scope_, id_,
                                  kNumArgs, &kArgName, arg_types, nullptr,
                                  arg_values, TRACE_EVENT_FLAG_HAS_ID);
}

void BlameContext::OnTraceLogEnabled() {
  DCHECK(WasInitialized());
  TakeSnapshot();
}

void BlameContext::OnTraceLogDisabled() {}

void BlameContext::AsValueInto(trace_event::TracedValue* state) {
  DCHECK(WasInitialized());
  if (!parent_id_)
    return;
  state->BeginDictionary("parent");
  state->SetString("id_ref", StringPrintf("0x%" PRIx64, parent_id_));
  state->SetString("scope", parent_scope_);
  state->EndDictionary();
}

void BlameContext::Initialize() {
  category_group_enabled_ =
      TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_);
  TRACE_EVENT_API_ADD_TRACE_EVENT(
      TRACE_EVENT_PHASE_CREATE_OBJECT, category_group_enabled_, type_, scope_,
      id_, 0, nullptr, nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID);
  trace_event::TraceLog::GetInstance()->AddEnabledStateObserver(this);
  TakeSnapshot();
}

bool BlameContext::WasInitialized() const {
  return category_group_enabled_ != nullptr;
}

}  // namespace trace_event
}  // namespace base