GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_report_module.cc Lines: 146 148 98.6 %
Date: 2022-08-21 04:19: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 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
22
  filename = TriggerNodeReport(
48
22
      isolate, env, *message, *trigger, filename, error);
49
  // Return value is the report filename
50
33
  info.GetReturnValue().Set(
51
22
      String::NewFromUtf8(isolate, filename.c_str()).ToLocalChecked());
52
11
}
53
54
// External JavaScript API for returning a report
55
9
void GetReport(const FunctionCallbackInfo<Value>& info) {
56
9
  Environment* env = Environment::GetCurrent(info);
57
9
  Isolate* isolate = env->isolate();
58
18
  HandleScope scope(isolate);
59
  Local<Object> error;
60
9
  std::ostringstream out;
61
62
9
  CHECK_EQ(info.Length(), 1);
63

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