GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_report_module.cc Lines: 148 150 98.7 %
Date: 2022-04-24 04:15:40 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
22
static void GetCompact(const FunctionCallbackInfo<Value>& info) {
79
22
  node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
80
44
  info.GetReturnValue().Set(node::per_process::cli_options->report_compact);
81
22
}
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
6
static void GetDirectory(const FunctionCallbackInfo<Value>& info) {
92
12
  node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
93
6
  Environment* env = Environment::GetCurrent(info);
94
6
  std::string directory = node::per_process::cli_options->report_directory;
95
6
  auto result = String::NewFromUtf8(env->isolate(), directory.c_str());
96
12
  info.GetReturnValue().Set(result.ToLocalChecked());
97
6
}
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
6
static void GetFilename(const FunctionCallbackInfo<Value>& info) {
108
12
  node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
109
6
  Environment* env = Environment::GetCurrent(info);
110
6
  std::string filename = node::per_process::cli_options->report_filename;
111
6
  auto result = String::NewFromUtf8(env->isolate(), filename.c_str());
112
12
  info.GetReturnValue().Set(result.ToLocalChecked());
113
6
}
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
17
static void GetSignal(const FunctionCallbackInfo<Value>& info) {
124
17
  Environment* env = Environment::GetCurrent(info);
125
17
  std::string signal = env->isolate_data()->options()->report_signal;
126
17
  auto result = String::NewFromUtf8(env->isolate(), signal.c_str());
127
34
  info.GetReturnValue().Set(result.ToLocalChecked());
128
17
}
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
6
static void ShouldReportOnFatalError(const FunctionCallbackInfo<Value>& info) {
138
6
  Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
139
6
  info.GetReturnValue().Set(
140
6
      node::per_process::cli_options->report_on_fatalerror);
141
6
}
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
5047
static void ShouldReportOnSignal(const FunctionCallbackInfo<Value>& info) {
150
5047
  Environment* env = Environment::GetCurrent(info);
151
10094
  info.GetReturnValue().Set(env->isolate_data()->options()->report_on_signal);
152
5047
}
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
10485
static void ShouldReportOnUncaughtException(
161
    const FunctionCallbackInfo<Value>& info) {
162
10485
  Environment* env = Environment::GetCurrent(info);
163
31455
  info.GetReturnValue().Set(
164
20970
      env->isolate_data()->options()->report_uncaught_exception);
165
10485
}
166
167
28036
static void SetReportOnUncaughtException(
168
    const FunctionCallbackInfo<Value>& info) {
169
28036
  Environment* env = Environment::GetCurrent(info);
170
28036
  CHECK(info[0]->IsBoolean());
171
28036
  env->isolate_data()->options()->report_uncaught_exception = info[0]->IsTrue();
172
28036
}
173
174
5604
static void Initialize(Local<Object> exports,
175
                       Local<Value> unused,
176
                       Local<Context> context,
177
                       void* priv) {
178
5604
  Environment* env = Environment::GetCurrent(context);
179
180
5604
  env->SetMethod(exports, "writeReport", WriteReport);
181
5604
  env->SetMethod(exports, "getReport", GetReport);
182
5604
  env->SetMethod(exports, "getCompact", GetCompact);
183
5604
  env->SetMethod(exports, "setCompact", SetCompact);
184
5604
  env->SetMethod(exports, "getDirectory", GetDirectory);
185
5604
  env->SetMethod(exports, "setDirectory", SetDirectory);
186
5604
  env->SetMethod(exports, "getFilename", GetFilename);
187
5604
  env->SetMethod(exports, "setFilename", SetFilename);
188
5604
  env->SetMethod(exports, "getSignal", GetSignal);
189
5604
  env->SetMethod(exports, "setSignal", SetSignal);
190
5604
  env->SetMethod(exports, "shouldReportOnFatalError", ShouldReportOnFatalError);
191
5604
  env->SetMethod(exports, "setReportOnFatalError", SetReportOnFatalError);
192
5604
  env->SetMethod(exports, "shouldReportOnSignal", ShouldReportOnSignal);
193
5604
  env->SetMethod(exports, "setReportOnSignal", SetReportOnSignal);
194
5604
  env->SetMethod(exports, "shouldReportOnUncaughtException",
195
                 ShouldReportOnUncaughtException);
196
5604
  env->SetMethod(exports, "setReportOnUncaughtException",
197
                 SetReportOnUncaughtException);
198
5604
}
199
200
5016
void RegisterExternalReferences(node::ExternalReferenceRegistry* registry) {
201
5016
  registry->Register(WriteReport);
202
5016
  registry->Register(GetReport);
203
5016
  registry->Register(GetCompact);
204
5016
  registry->Register(SetCompact);
205
5016
  registry->Register(GetDirectory);
206
5016
  registry->Register(SetDirectory);
207
5016
  registry->Register(GetFilename);
208
5016
  registry->Register(SetFilename);
209
5016
  registry->Register(GetSignal);
210
5016
  registry->Register(SetSignal);
211
5016
  registry->Register(ShouldReportOnFatalError);
212
5016
  registry->Register(SetReportOnFatalError);
213
5016
  registry->Register(ShouldReportOnSignal);
214
5016
  registry->Register(SetReportOnSignal);
215
5016
  registry->Register(ShouldReportOnUncaughtException);
216
5016
  registry->Register(SetReportOnUncaughtException);
217
5016
}
218
219
}  // namespace report
220
221
5083
NODE_MODULE_CONTEXT_AWARE_INTERNAL(report, report::Initialize)
222
5016
NODE_MODULE_EXTERNAL_REFERENCE(report, report::RegisterExternalReferences)