src: handle report options on fatalerror · nodejs/node@04237ec · GitHub
Skip to content

Commit 04237ec

Browse files
sam-githubMylesBorins
authored andcommitted
src: handle report options on fatalerror
Follow on to #32207, 3 other options are also not respected under situations that the isolate is not available. PR-URL: #32497 Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent 979fb15 commit 04237ec

5 files changed

Lines changed: 154 additions & 57 deletions

File tree

src/node_options.cc

Lines changed: 14 additions & 14 deletions

src/node_options.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,7 @@ class PerIsolateOptions : public Options {
186186
bool no_node_snapshot = false;
187187
bool report_uncaught_exception = false;
188188
bool report_on_signal = false;
189-
bool report_compact = false;
190189
std::string report_signal = "SIGUSR2";
191-
std::string report_filename;
192-
std::string report_directory;
193190
inline EnvironmentOptions* get_per_env_options();
194191
void CheckOptions(std::vector<std::string>* errors) override;
195192
};
@@ -236,6 +233,9 @@ class PerProcessOptions : public Options {
236233
bool trace_sigint = false;
237234
std::vector<std::string> cmdline;
238235
bool report_on_fatalerror = false;
236+
bool report_compact = false;
237+
std::string report_directory;
238+
std::string report_filename;
239239

240240
inline PerIsolateOptions* get_per_isolate_options();
241241
void CheckOptions(std::vector<std::string>* errors) override;

src/node_report.cc

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ using node::DiagnosticFilename;
3232
using node::Environment;
3333
using node::Mutex;
3434
using node::NativeSymbolDebuggingContext;
35-
using node::PerIsolateOptions;
3635
using node::TIME_TYPE;
3736
using node::worker::Worker;
3837
using v8::HeapSpaceStatistics;
@@ -45,6 +44,8 @@ using v8::String;
4544
using v8::V8;
4645
using v8::Value;
4746

47+
namespace per_process = node::per_process;
48+
4849
// Internal/static function declarations
4950
static void WriteNodeReport(Isolate* isolate,
5051
Environment* env,
@@ -70,29 +71,32 @@ static void PrintCpuInfo(JSONWriter* writer);
7071
static void PrintNetworkInterfaceInfo(JSONWriter* writer);
7172

7273
// External function to trigger a report, writing to file.
73-
// The 'name' parameter is in/out: an input filename is used
74-
// if supplied, and the actual filename is returned.
7574
std::string TriggerNodeReport(Isolate* isolate,
7675
Environment* env,
7776
const char* message,
7877
const char* trigger,
7978
const std::string& name,
8079
Local<String> stackstr) {
8180
std::string filename;
82-
std::shared_ptr<PerIsolateOptions> options;
83-
if (env != nullptr) options = env->isolate_data()->options();
8481

8582
// Determine the required report filename. In order of priority:
8683
// 1) supplied on API 2) configured on startup 3) default generated
8784
if (!name.empty()) {
8885
// Filename was specified as API parameter.
8986
filename = name;
90-
} else if (env != nullptr && options->report_filename.length() > 0) {
91-
// File name was supplied via start-up option.
92-
filename = options->report_filename;
9387
} else {
94-
filename = *DiagnosticFilename(env != nullptr ? env->thread_id() : 0,
95-
"report", "json");
88+
std::string report_filename;
89+
{
90+
Mutex::ScopedLock lock(per_process::cli_options_mutex);
91+
report_filename = per_process::cli_options->report_filename;
92+
}
93+
if (report_filename.length() > 0) {
94+
// File name was supplied via start-up option.
95+
filename = report_filename;
96+
} else {
97+
filename = *DiagnosticFilename(env != nullptr ? env->thread_id() : 0,
98+
"report", "json");
99+
}
96100
}
97101

98102
// Open the report file stream for writing. Supports stdout/err,
@@ -104,9 +108,14 @@ std::string TriggerNodeReport(Isolate* isolate,
104108
} else if (filename == "stderr") {
105109
outstream = &std::cerr;
106110
} else {
111+
std::string report_directory;
112+
{
113+
Mutex::ScopedLock lock(per_process::cli_options_mutex);
114+
report_directory = per_process::cli_options->report_directory;
115+
}
107116
// Regular file. Append filename to directory path if one was specified
108-
if (env != nullptr && options->report_directory.length() > 0) {
109-
std::string pathname = options->report_directory;
117+
if (report_directory.length() > 0) {
118+
std::string pathname = report_directory;
110119
pathname += node::kPathSeparator;
111120
pathname += filename;
112121
outfile.open(pathname, std::ios::out | std::ios::binary);
@@ -117,8 +126,8 @@ std::string TriggerNodeReport(Isolate* isolate,
117126
if (!outfile.is_open()) {
118127
std::cerr << "\nFailed to open Node.js report file: " << filename;
119128

120-
if (env != nullptr && options->report_directory.length() > 0)
121-
std::cerr << " directory: " << options->report_directory;
129+
if (report_directory.length() > 0)
130+
std::cerr << " directory: " << report_directory;
122131

123132
std::cerr << " (errno: " << errno << ")" << std::endl;
124133
return "";
@@ -127,7 +136,11 @@ std::string TriggerNodeReport(Isolate* isolate,
127136
std::cerr << "\nWriting Node.js report to file: " << filename;
128137
}
129138

130-
bool compact = env != nullptr ? options->report_compact : true;
139+
bool compact;
140+
{
141+
Mutex::ScopedLock lock(per_process::cli_options_mutex);
142+
compact = per_process::cli_options->report_compact;
143+
}
131144
WriteNodeReport(isolate, env, message, trigger, filename, *outstream,
132145
stackstr, compact);
133146

@@ -136,7 +149,10 @@ std::string TriggerNodeReport(Isolate* isolate,
136149
outfile.close();
137150
}
138151

139-
std::cerr << "\nNode.js report completed" << std::endl;
152+
// Do not mix JSON and free-form text on stderr.
153+
if (filename != "stderr") {
154+
std::cerr << "\nNode.js report completed" << std::endl;
155+
}
140156
return filename;
141157
}
142158

src/node_report_module.cc

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,47 +69,52 @@ void GetReport(const FunctionCallbackInfo<Value>& info) {
6969
}
7070

7171
static void GetCompact(const FunctionCallbackInfo<Value>& info) {
72-
Environment* env = Environment::GetCurrent(info);
73-
info.GetReturnValue().Set(env->isolate_data()->options()->report_compact);
72+
node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
73+
info.GetReturnValue().Set(node::per_process::cli_options->report_compact);
7474
}
7575

7676
static void SetCompact(const FunctionCallbackInfo<Value>& info) {
77+
node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
7778
Environment* env = Environment::GetCurrent(info);
7879
Isolate* isolate = env->isolate();
7980
bool compact = info[0]->ToBoolean(isolate)->Value();
80-
env->isolate_data()->options()->report_compact = compact;
81+
node::per_process::cli_options->report_compact = compact;
8182
}
8283

8384
static void GetDirectory(const FunctionCallbackInfo<Value>& info) {
85+
node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
8486
Environment* env = Environment::GetCurrent(info);
85-
std::string directory = env->isolate_data()->options()->report_directory;
87+
std::string directory = node::per_process::cli_options->report_directory;
8688
auto result = String::NewFromUtf8(env->isolate(),
8789
directory.c_str(),
8890
v8::NewStringType::kNormal);
8991
info.GetReturnValue().Set(result.ToLocalChecked());
9092
}
9193

9294
static void SetDirectory(const FunctionCallbackInfo<Value>& info) {
95+
node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
9396
Environment* env = Environment::GetCurrent(info);
9497
CHECK(info[0]->IsString());
9598
Utf8Value dir(env->isolate(), info[0].As<String>());
96-
env->isolate_data()->options()->report_directory = *dir;
99+
node::per_process::cli_options->report_directory = *dir;
97100
}
98101

99102
static void GetFilename(const FunctionCallbackInfo<Value>& info) {
103+
node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
100104
Environment* env = Environment::GetCurrent(info);
101-
std::string filename = env->isolate_data()->options()->report_filename;
105+
std::string filename = node::per_process::cli_options->report_filename;
102106
auto result = String::NewFromUtf8(env->isolate(),
103107
filename.c_str(),
104108
v8::NewStringType::kNormal);
105109
info.GetReturnValue().Set(result.ToLocalChecked());
106110
}
107111

108112
static void SetFilename(const FunctionCallbackInfo<Value>& info) {
113+
node::Mutex::ScopedLock lock(node::per_process::cli_options_mutex);
109114
Environment* env = Environment::GetCurrent(info);
110115
CHECK(info[0]->IsString());
111116
Utf8Value name(env->isolate(), info[0].As<String>());
112-
env->isolate_data()->options()->report_filename = *name;
117+
node::per_process::cli_options->report_filename = *name;
113118
}
114119

115120
static void GetSignal(const FunctionCallbackInfo<Value>& info) {
Lines changed: 93 additions & 17 deletions

0 commit comments

Comments
 (0)