GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_report_module.cc Lines: 148 150 98.7 %
Date: 2021-09-19 04:12:45 Branches: 28 46 60.9 %

Line Branch Exec Source
1
#include "env.h"
2
#include "node_errors.h"
3
#include "node_external_reference.h"
4
#include "node_internals.h"
5
#include "node_options.h"
6
#include "node_report.h"
7
#include "util-inl.h"
8
9
#include "handle_wrap.h"
10
#include "node_buffer.h"
11
#include "stream_base-inl.h"
12
#include "stream_wrap.h"
13
14
#include <v8.h>
15
#include <atomic>
16
#include <sstream>
17
18
namespace report {
19
using node::Environment;
20
using node::Mutex;
21
using node::Utf8Value;
22
using v8::Context;
23
using v8::FunctionCallbackInfo;
24
using v8::HandleScope;
25
using v8::Isolate;
26
using v8::Local;
27
using v8::Object;
28
using v8::String;
29
using v8::Value;
30
31
15
void WriteReport(const FunctionCallbackInfo<Value>& info) {
32
15
  Environment* env = Environment::GetCurrent(info);
33
15
  Isolate* isolate = env->isolate();
34
30
  HandleScope scope(isolate);
35
30
  std::string filename;
36
  Local<Value> error;
37
38
15
  CHECK_EQ(info.Length(), 4);
39
45
  String::Utf8Value message(isolate, info[0].As<String>());
40
30
  String::Utf8Value trigger(isolate, info[1].As<String>());
41
42
30
  if (info[2]->IsString())
43
4
    filename = *String::Utf8Value(isolate, info[2]);
44
15
  if (!info[3].IsEmpty())
45
15
    error = info[3];
46
  else
47
    error = Local<Value>();
48
49
30
  filename = TriggerNodeReport(
50
30
      isolate, env, *message, *trigger, filename, error);
51
  // Return value is the report filename
52
45
  info.GetReturnValue().Set(
53
30
      String::NewFromUtf8(isolate, filename.c_str()).ToLocalChecked());
54
15
}
55
56
// External JavaScript API for returning a report
57
8
void GetReport(const FunctionCallbackInfo<Value>& info) {
58
8
  Environment* env = Environment::GetCurrent(info);
59
8
  Isolate* isolate = env->isolate();
60
16
  HandleScope scope(isolate);
61
  Local<Object> error;
62
8
  std::ostringstream out;
63
64
8
  CHECK_EQ(info.Length(), 1);
65

16
  if (!info[0].IsEmpty() && info[0]->IsObject())
66
16
    error = info[0].As<Object>();
67
  else
68
    error = Local<Object>();
69
70
8
  GetNodeReport(
71
      isolate, env, "JavaScript API", __func__, error, out);
72
73
  // Return value is the contents of a report as a string.
74
24
  info.GetReturnValue().Set(
75
16
      String::NewFromUtf8(isolate, out.str().c_str()).ToLocalChecked());
76
8
}
77
78
20
static void GetCompact(const FunctionCallbackInfo<Value>& info) {
79
20
  node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
80
40
  info.GetReturnValue().Set(node::per_process::cli_options->report_compact);
81
20
}
82
83
2
static void SetCompact(const FunctionCallbackInfo<Value>& info) {
84
2
  node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
85
2
  Environment* env = Environment::GetCurrent(info);
86
2
  Isolate* isolate = env->isolate();
87
4
  bool compact = info[0]->ToBoolean(isolate)->Value();
88
2
  node::per_process::cli_options->report_compact = compact;
89
2
}
90
91
4
static void GetDirectory(const FunctionCallbackInfo<Value>& info) {
92
8
  node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
93
4
  Environment* env = Environment::GetCurrent(info);
94
4
  std::string directory = node::per_process::cli_options->report_directory;
95
4
  auto result = String::NewFromUtf8(env->isolate(), directory.c_str());
96
8
  info.GetReturnValue().Set(result.ToLocalChecked());
97
4
}
98
99
8
static void SetDirectory(const FunctionCallbackInfo<Value>& info) {
100
16
  node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
101
8
  Environment* env = Environment::GetCurrent(info);
102
16
  CHECK(info[0]->IsString());
103
24
  Utf8Value dir(env->isolate(), info[0].As<String>());
104
8
  node::per_process::cli_options->report_directory = *dir;
105
8
}
106
107
4
static void GetFilename(const FunctionCallbackInfo<Value>& info) {
108
8
  node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
109
4
  Environment* env = Environment::GetCurrent(info);
110
4
  std::string filename = node::per_process::cli_options->report_filename;
111
4
  auto result = String::NewFromUtf8(env->isolate(), filename.c_str());
112
8
  info.GetReturnValue().Set(result.ToLocalChecked());
113
4
}
114
115
2
static void SetFilename(const FunctionCallbackInfo<Value>& info) {
116
4
  node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
117
2
  Environment* env = Environment::GetCurrent(info);
118
4
  CHECK(info[0]->IsString());
119
6
  Utf8Value name(env->isolate(), info[0].As<String>());
120
2
  node::per_process::cli_options->report_filename = *name;
121
2
}
122
123
15
static void GetSignal(const FunctionCallbackInfo<Value>& info) {
124
15
  Environment* env = Environment::GetCurrent(info);
125
15
  std::string signal = env->isolate_data()->options()->report_signal;
126
15
  auto result = String::NewFromUtf8(env->isolate(), signal.c_str());
127
30
  info.GetReturnValue().Set(result.ToLocalChecked());
128
15
}
129
130
3
static void SetSignal(const FunctionCallbackInfo<Value>& info) {
131
3
  Environment* env = Environment::GetCurrent(info);
132
6
  CHECK(info[0]->IsString());
133
6
  Utf8Value signal(env->isolate(), info[0].As<String>());
134
3
  env->isolate_data()->options()->report_signal = *signal;
135
3
}
136
137
4
static void ShouldReportOnFatalError(const FunctionCallbackInfo<Value>& info) {
138
4
  Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
139
4
  info.GetReturnValue().Set(
140
4
      node::per_process::cli_options->report_on_fatalerror);
141
4
}
142
143
2
static void SetReportOnFatalError(const FunctionCallbackInfo<Value>& info) {
144
2
  CHECK(info[0]->IsBoolean());
145
2
  Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
146
2
  node::per_process::cli_options->report_on_fatalerror = info[0]->IsTrue();
147
2
}
148
149
4880
static void ShouldReportOnSignal(const FunctionCallbackInfo<Value>& info) {
150
4880
  Environment* env = Environment::GetCurrent(info);
151
9760
  info.GetReturnValue().Set(env->isolate_data()->options()->report_on_signal);
152
4880
}
153
154
5
static void SetReportOnSignal(const FunctionCallbackInfo<Value>& info) {
155
5
  Environment* env = Environment::GetCurrent(info);
156
5
  CHECK(info[0]->IsBoolean());
157
5
  env->isolate_data()->options()->report_on_signal = info[0]->IsTrue();
158
5
}
159
160
10108
static void ShouldReportOnUncaughtException(
161
    const FunctionCallbackInfo<Value>& info) {
162
10108
  Environment* env = Environment::GetCurrent(info);
163
30324
  info.GetReturnValue().Set(
164
20216
      env->isolate_data()->options()->report_uncaught_exception);
165
10108
}
166
167
27143
static void SetReportOnUncaughtException(
168
    const FunctionCallbackInfo<Value>& info) {
169
27143
  Environment* env = Environment::GetCurrent(info);
170
27143
  CHECK(info[0]->IsBoolean());
171
27143
  env->isolate_data()->options()->report_uncaught_exception = info[0]->IsTrue();
172
27143
}
173
174
5433
static void Initialize(Local<Object> exports,
175
                       Local<Value> unused,
176
                       Local<Context> context,
177
                       void* priv) {
178
5433
  Environment* env = Environment::GetCurrent(context);
179
180
5433
  env->SetMethod(exports, "writeReport", WriteReport);
181
5433
  env->SetMethod(exports, "getReport", GetReport);
182
5433
  env->SetMethod(exports, "getCompact", GetCompact);
183
5433
  env->SetMethod(exports, "setCompact", SetCompact);
184
5433
  env->SetMethod(exports, "getDirectory", GetDirectory);
185
5433
  env->SetMethod(exports, "setDirectory", SetDirectory);
186
5433
  env->SetMethod(exports, "getFilename", GetFilename);
187
5433
  env->SetMethod(exports, "setFilename", SetFilename);
188
5433
  env->SetMethod(exports, "getSignal", GetSignal);
189
5433
  env->SetMethod(exports, "setSignal", SetSignal);
190
5433
  env->SetMethod(exports, "shouldReportOnFatalError", ShouldReportOnFatalError);
191
5433
  env->SetMethod(exports, "setReportOnFatalError", SetReportOnFatalError);
192
5433
  env->SetMethod(exports, "shouldReportOnSignal", ShouldReportOnSignal);
193
5433
  env->SetMethod(exports, "setReportOnSignal", SetReportOnSignal);
194
5433
  env->SetMethod(exports, "shouldReportOnUncaughtException",
195
                 ShouldReportOnUncaughtException);
196
5433
  env->SetMethod(exports, "setReportOnUncaughtException",
197
                 SetReportOnUncaughtException);
198
5433
}
199
200
4851
void RegisterExternalReferences(node::ExternalReferenceRegistry* registry) {
201
4851
  registry->Register(WriteReport);
202
4851
  registry->Register(GetReport);
203
4851
  registry->Register(GetCompact);
204
4851
  registry->Register(SetCompact);
205
4851
  registry->Register(GetDirectory);
206
4851
  registry->Register(SetDirectory);
207
4851
  registry->Register(GetFilename);
208
4851
  registry->Register(SetFilename);
209
4851
  registry->Register(GetSignal);
210
4851
  registry->Register(SetSignal);
211
4851
  registry->Register(ShouldReportOnFatalError);
212
4851
  registry->Register(SetReportOnFatalError);
213
4851
  registry->Register(ShouldReportOnSignal);
214
4851
  registry->Register(SetReportOnSignal);
215
4851
  registry->Register(ShouldReportOnUncaughtException);
216
4851
  registry->Register(SetReportOnUncaughtException);
217
4851
}
218
219
}  // namespace report
220
221
4924
NODE_MODULE_CONTEXT_AWARE_INTERNAL(report, report::Initialize)
222
4851
NODE_MODULE_EXTERNAL_REFERENCE(report, report::RegisterExternalReferences)