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

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