GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_report_module.cc Lines: 145 147 98.6 %
Date: 2022-09-19 04:21:54 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 node {
19
namespace report {
20
using v8::Context;
21
using v8::FunctionCallbackInfo;
22
using v8::HandleScope;
23
using v8::Isolate;
24
using v8::Local;
25
using v8::Object;
26
using v8::String;
27
using v8::Value;
28
29
11
void WriteReport(const FunctionCallbackInfo<Value>& info) {
30
11
  Environment* env = Environment::GetCurrent(info);
31
11
  Isolate* isolate = env->isolate();
32
22
  HandleScope scope(isolate);
33
22
  std::string filename;
34
  Local<Value> error;
35
36
11
  CHECK_EQ(info.Length(), 4);
37
33
  String::Utf8Value message(isolate, info[0].As<String>());
38
22
  String::Utf8Value trigger(isolate, info[1].As<String>());
39
40
22
  if (info[2]->IsString())
41
4
    filename = *String::Utf8Value(isolate, info[2]);
42
11
  if (!info[3].IsEmpty())
43
11
    error = info[3];
44
  else
45
    error = Local<Value>();
46
47
11
  filename = TriggerNodeReport(env, *message, *trigger, filename, error);
48
  // Return value is the report filename
49
33
  info.GetReturnValue().Set(
50
22
      String::NewFromUtf8(isolate, filename.c_str()).ToLocalChecked());
51
11
}
52
53
// External JavaScript API for returning a report
54
9
void GetReport(const FunctionCallbackInfo<Value>& info) {
55
9
  Environment* env = Environment::GetCurrent(info);
56
9
  Isolate* isolate = env->isolate();
57
18
  HandleScope scope(isolate);
58
  Local<Object> error;
59
9
  std::ostringstream out;
60
61
9
  CHECK_EQ(info.Length(), 1);
62

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