GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_trace_events.cc Lines: 74 78 94.9 %
Date: 2022-11-04 03:21:42 Branches: 19 34 55.9 %

Line Branch Exec Source
1
#include "base_object-inl.h"
2
#include "env-inl.h"
3
#include "memory_tracker-inl.h"
4
#include "node.h"
5
#include "node_external_reference.h"
6
#include "node_internals.h"
7
#include "node_v8_platform-inl.h"
8
#include "tracing/agent.h"
9
#include "util-inl.h"
10
11
#include <set>
12
#include <string>
13
14
namespace node {
15
16
class ExternalReferenceRegistry;
17
18
using v8::Array;
19
using v8::Context;
20
using v8::Function;
21
using v8::FunctionCallbackInfo;
22
using v8::FunctionTemplate;
23
using v8::Isolate;
24
using v8::Local;
25
using v8::NewStringType;
26
using v8::Object;
27
using v8::String;
28
using v8::Value;
29
30
class NodeCategorySet : public BaseObject {
31
 public:
32
  static void Initialize(Local<Object> target,
33
                  Local<Value> unused,
34
                  Local<Context> context,
35
                  void* priv);
36
  static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
37
  static void New(const FunctionCallbackInfo<Value>& args);
38
  static void Enable(const FunctionCallbackInfo<Value>& args);
39
  static void Disable(const FunctionCallbackInfo<Value>& args);
40
41
26
  const std::set<std::string>& GetCategories() const { return categories_; }
42
43
  void MemoryInfo(MemoryTracker* tracker) const override {
44
    tracker->TrackField("categories", categories_);
45
  }
46
47
  SET_MEMORY_INFO_NAME(NodeCategorySet)
48
  SET_SELF_SIZE(NodeCategorySet)
49
50
 private:
51
19
  NodeCategorySet(Environment* env,
52
                  Local<Object> wrap,
53
19
                  std::set<std::string>&& categories) :
54
19
        BaseObject(env, wrap), categories_(std::move(categories)) {
55
19
    MakeWeak();
56
19
  }
57
58
  bool enabled_ = false;
59
  const std::set<std::string> categories_;
60
};
61
62
19
void NodeCategorySet::New(const FunctionCallbackInfo<Value>& args) {
63
19
  Environment* env = Environment::GetCurrent(args);
64
19
  std::set<std::string> categories;
65
19
  CHECK(args[0]->IsArray());
66
19
  Local<Array> cats = args[0].As<Array>();
67
76
  for (size_t n = 0; n < cats->Length(); n++) {
68
    Local<Value> category;
69
38
    if (!cats->Get(env->context(), n).ToLocal(&category)) return;
70
19
    Utf8Value val(env->isolate(), category);
71
19
    if (!*val) return;
72
19
    categories.emplace(*val);
73
  }
74
19
  CHECK_NOT_NULL(GetTracingAgentWriter());
75
19
  new NodeCategorySet(env, args.This(), std::move(categories));
76
}
77
78
20
void NodeCategorySet::Enable(const FunctionCallbackInfo<Value>& args) {
79
  NodeCategorySet* category_set;
80
20
  ASSIGN_OR_RETURN_UNWRAP(&category_set, args.Holder());
81
20
  CHECK_NOT_NULL(category_set);
82
20
  const auto& categories = category_set->GetCategories();
83

20
  if (!category_set->enabled_ && !categories.empty()) {
84
    // Starts the Tracing Agent if it wasn't started already (e.g. through
85
    // a command line flag.)
86
20
    StartTracingAgent();
87
20
    GetTracingAgentWriter()->Enable(categories);
88
20
    category_set->enabled_ = true;
89
  }
90
}
91
92
6
void NodeCategorySet::Disable(const FunctionCallbackInfo<Value>& args) {
93
  NodeCategorySet* category_set;
94
6
  ASSIGN_OR_RETURN_UNWRAP(&category_set, args.Holder());
95
6
  CHECK_NOT_NULL(category_set);
96
6
  const auto& categories = category_set->GetCategories();
97

6
  if (category_set->enabled_ && !categories.empty()) {
98
6
    GetTracingAgentWriter()->Disable(categories);
99
6
    category_set->enabled_ = false;
100
  }
101
}
102
103
17
void GetEnabledCategories(const FunctionCallbackInfo<Value>& args) {
104
17
  Environment* env = Environment::GetCurrent(args);
105
  std::string categories =
106
34
      GetTracingAgentWriter()->agent()->GetEnabledCategories();
107
17
  if (!categories.empty()) {
108
42
    args.GetReturnValue().Set(
109
14
      String::NewFromUtf8(env->isolate(),
110
                          categories.c_str(),
111
                          NewStringType::kNormal,
112
14
                          categories.size()).ToLocalChecked());
113
  }
114
17
}
115
116
784
static void SetTraceCategoryStateUpdateHandler(
117
    const FunctionCallbackInfo<Value>& args) {
118
784
  Environment* env = Environment::GetCurrent(args);
119
784
  CHECK(args[0]->IsFunction());
120
1568
  env->set_trace_category_state_function(args[0].As<Function>());
121
784
}
122
123
784
void NodeCategorySet::Initialize(Local<Object> target,
124
                Local<Value> unused,
125
                Local<Context> context,
126
                void* priv) {
127
784
  Environment* env = Environment::GetCurrent(context);
128
784
  Isolate* isolate = env->isolate();
129
130
784
  SetMethod(context, target, "getEnabledCategories", GetEnabledCategories);
131
784
  SetMethod(context,
132
            target,
133
            "setTraceCategoryStateUpdateHandler",
134
            SetTraceCategoryStateUpdateHandler);
135
136
  Local<FunctionTemplate> category_set =
137
784
      NewFunctionTemplate(isolate, NodeCategorySet::New);
138
1568
  category_set->InstanceTemplate()->SetInternalFieldCount(
139
      NodeCategorySet::kInternalFieldCount);
140
784
  category_set->Inherit(BaseObject::GetConstructorTemplate(env));
141
784
  SetProtoMethod(isolate, category_set, "enable", NodeCategorySet::Enable);
142
784
  SetProtoMethod(isolate, category_set, "disable", NodeCategorySet::Disable);
143
144
784
  SetConstructorFunction(context, target, "CategorySet", category_set);
145
146
  Local<String> isTraceCategoryEnabled =
147
784
      FIXED_ONE_BYTE_STRING(env->isolate(), "isTraceCategoryEnabled");
148
784
  Local<String> trace = FIXED_ONE_BYTE_STRING(env->isolate(), "trace");
149
150
  // Grab the trace and isTraceCategoryEnabled intrinsics from the binding
151
  // object and expose those to our binding layer.
152
784
  Local<Object> binding = context->GetExtrasBindingObject();
153
784
  target->Set(context, isTraceCategoryEnabled,
154
2352
              binding->Get(context, isTraceCategoryEnabled).ToLocalChecked())
155
                  .Check();
156
784
  target->Set(context, trace,
157
1568
              binding->Get(context, trace).ToLocalChecked()).Check();
158
784
}
159
160
5586
void NodeCategorySet::RegisterExternalReferences(
161
    ExternalReferenceRegistry* registry) {
162
5586
  registry->Register(GetEnabledCategories);
163
5586
  registry->Register(SetTraceCategoryStateUpdateHandler);
164
5586
  registry->Register(NodeCategorySet::New);
165
5586
  registry->Register(NodeCategorySet::Enable);
166
5586
  registry->Register(NodeCategorySet::Disable);
167
5586
}
168
169
}  // namespace node
170
171
5657
NODE_MODULE_CONTEXT_AWARE_INTERNAL(trace_events,
172
                                   node::NodeCategorySet::Initialize)
173
5586
NODE_MODULE_EXTERNAL_REFERENCE(
174
    trace_events, node::NodeCategorySet::RegisterExternalReferences)