Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:33

0001 
0002 // Copyright 2020, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 #include "JSignalHandler.h"
0006 
0007 #include <JANA/JApplication.h>
0008 #include <JANA/Engine/JExecutionEngine.h>
0009 #include <JANA/Utils/JBacktrace.h>
0010 
0011 #include <unistd.h>
0012 #include <csignal>
0013 
0014 /// JSignalHandler bundles together the logic for querying a JApplication
0015 /// about its JStatus with signal handlers for USR1, USR2, and CTRL-C.
0016 namespace JSignalHandler {
0017 
0018 JApplication* g_app;
0019 JLogger* g_logger;
0020 
0021 
0022 /// Handle SIGINT signals (e.g. from hitting Ctrl-C). When a SIGINT
0023 /// is received, JANA will try and shutdown the program cleanly, allowing
0024 /// the processing threads to finish up the events they are working on.
0025 /// The first 2 SIGINT signals received will tell JANA to shutdown gracefully.
0026 /// On the 3rd SIGINT, the program will try to exit immediately.
0027 void handle_sigint(int) {
0028     if (g_app->IsInitialized()) {
0029         g_app->GetService<JExecutionEngine>()->HandleSIGINT();
0030     }
0031     else {
0032         exit(-2);
0033     }
0034 }
0035 
0036 void handle_usr1(int) {
0037     if (g_app->IsInitialized()) {
0038         g_app->GetService<JExecutionEngine>()->HandleSIGUSR1();
0039     }
0040 }
0041 
0042 void handle_usr2(int) {
0043     if (g_app->IsInitialized()) {
0044         g_app->GetService<JExecutionEngine>()->HandleSIGUSR2();
0045     }
0046 }
0047 
0048 void handle_tstp(int) {
0049     if (g_app->IsInitialized()) {
0050         g_app->GetService<JExecutionEngine>()->HandleSIGTSTP();
0051     }
0052 }
0053 
0054 void handle_sigsegv(int /*signal_number*/, siginfo_t* /*signal_info*/, void* /*context*/) {
0055     LOG_FATAL(*g_logger) << "Segfault detected!" << LOG_END;
0056     JBacktrace backtrace;
0057     backtrace.Capture(3);
0058     LOG_FATAL(*g_logger) << "Hard exit due to segmentation fault! Backtrace:\n\n" << backtrace.ToString() << LOG_END;
0059     _exit(static_cast<int>(JApplication::ExitCode::Segfault)); 
0060     // _exit() is async-signal-safe, whereas exit() is not
0061 }
0062 
0063 
0064 /// Add special handles for system signals.
0065 void register_handlers(JApplication* app) {
0066     assert (app != nullptr);
0067     g_app = app;
0068     g_logger = &default_cout_logger;
0069     *g_logger = app->GetJParameterManager()->GetLogger("jana");
0070     // Note that this updates the static default_cout_logger to match the user-provided jana:loglevel.
0071     // It would be nice to do this in a less unexpected place, and hopefully that will naturally
0072     // emerge from future refactorings.
0073 
0074     // We capture a dummy backtrace to warm it up before it gets called inside a signal handler.
0075     // Because backtrace() dynamically loads libgcc, calling malloc() in the process, it is not
0076     // async-signal-safe until this warmup has happened. Thus we prevent a rare deadlock and several
0077     // TSAN and Helgrind warnings.
0078     JBacktrace backtrace;
0079     backtrace.Capture();
0080 
0081     //Define signal action
0082     struct sigaction sSignalAction;
0083     sSignalAction.sa_sigaction = handle_sigsegv;
0084     sSignalAction.sa_flags = SA_RESTART | SA_SIGINFO;
0085 
0086     //Clear and set signals
0087     sigemptyset(&sSignalAction.sa_mask);
0088     sigaction(SIGSEGV, &sSignalAction, nullptr);
0089 
0090     LOG_WARN(*g_logger) << "Setting signal handler USR1. Use to write status info to the named pipe." << LOG_END;
0091     signal(SIGUSR1, handle_usr1);
0092     signal(SIGUSR2, handle_usr2);
0093     signal(SIGTSTP, handle_tstp);
0094     LOG_WARN(*g_logger) << "Setting signal handler SIGINT (Ctrl-C). Use a single SIGINT to enter the Inspector, or multiple SIGINTs for an immediate shutdown." << LOG_END;
0095     signal(SIGINT,  handle_sigint);
0096 }
0097 
0098 
0099 }; // namespace JSignalHandler
0100