Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

report: catch internal segfaults #25915

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/node_errors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,21 @@ void PrintErrorString(const char* format, ...) {
ABORT();
}

#ifndef _WIN32
void OnSIGSEGV(int signo) {
uv_tty_reset_mode();
#ifdef __FreeBSD__
// FreeBSD has a nasty bug, see RegisterSignalHandler for details
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
CHECK_EQ(sigaction(signo, &sa, nullptr), 0);
#endif
CHECK_EQ(signo, SIGSEGV);
OnFatalError(__func__, "caught internal error.");
}
#endif // _WIN32

void OnFatalError(const char* location, const char* message) {
if (location) {
PrintErrorString("FATAL ERROR: %s %s\n", location, message);
Expand Down
3 changes: 3 additions & 0 deletions src/node_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ void AppendExceptionLine(Environment* env,

[[noreturn]] void FatalError(const char* location, const char* message);
void OnFatalError(const char* location, const char* message);
#ifndef _WIN32
void OnSIGSEGV(int signo);
#endif // _WIN32

// Like a `TryCatch` but exits the process if an exception was caught.
class FatalTryCatch : public v8::TryCatch {
Expand Down
15 changes: 15 additions & 0 deletions src/node_report_module.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "env.h"
#include "node.h"
#include "node_errors.h"
#include "node_internals.h"
#include "node_options.h"
Expand Down Expand Up @@ -262,6 +263,20 @@ static void Initialize(Local<Object> exports,
env->SetMethod(exports, "onUserSignal", OnUserSignal);
env->SetMethod(exports, "syncConfig", SyncConfig);

// Libuv based signal handling does not help internal segfaults,
// as synchronously delivered signals are handled asynchronously
// in libuv at present, which Node.js is unable to effectively
// consume. So install one of our own; make sure reset tty mode
// and exit; do not return gracefully that causes fault context
// to be invoked again.
// TODO(gireeshpunathil) decide what to do with asynchronous
// sigsegv handling - handle separately, or merge with this one.
#ifndef _WIN32
if (options->report_on_fatalerror) {
node::RegisterSignalHandler(SIGSEGV, node::OnSIGSEGV, true);
}
#endif // _WIN32

// TODO(gireeshpunathil) if we are retaining this flag,
// insert more verbose information at vital control flow
// points. Right now, it is only this one.
Expand Down