23    static SignalHandler instance;
 
 
   31    sa.sa_sigaction = SignalHandler::handleSignal; 
 
   32    sigemptyset(&sa.sa_mask);
 
   33    sa.sa_flags = SA_SIGINFO; 
 
   35    sigaction(SIGABRT, &sa, 
nullptr); 
 
   36    sigaction(SIGSEGV, &sa, 
nullptr); 
 
 
   48  static auto getCurrentTimestamp() -> std::string
 
   50    std::time_t now = std::time(
nullptr);
 
   52    std::strftime(buffer, 
sizeof(buffer), 
"%Y-%m-%d %H:%M:%S", std::localtime(&now));
 
   53    return std::string(buffer);
 
   56  static void createCacheDirectory(
const std::string& path)
 
   59    if (stat(path.c_str(), &info) != 0 || !(info.st_mode & S_IFDIR))
 
   61      mkdir(path.c_str(), 0755); 
 
   66  static void logSystemInfo(std::ofstream& logFile)
 
   69    logFile << 
"Process ID: " << getpid() << 
"\n";
 
   70    logFile << 
"Parent Process ID: " << getppid() << 
"\n";
 
   71    logFile << 
"Thread ID: " << pthread_self() << 
"\n";
 
   75    if (getcwd(cwd, 
sizeof(cwd)))
 
   77      logFile << 
"Current Working Directory: " << cwd << 
"\n";
 
   81    struct utsname sysInfo;
 
   82    if (uname(&sysInfo) == 0)
 
   84      logFile << 
"System Name: " << sysInfo.sysname << 
"\n";
 
   85      logFile << 
"Node Name: " << sysInfo.nodename << 
"\n";
 
   86      logFile << 
"Release: " << sysInfo.release << 
"\n";
 
   87      logFile << 
"Version: " << sysInfo.version << 
"\n";
 
   88      logFile << 
"Machine: " << sysInfo.machine << 
"\n";
 
   93    if (getrusage(RUSAGE_SELF, &usage) == 0)
 
   95      logFile << 
"CPU Time Used (user): " << usage.ru_utime.tv_sec << 
"s " << usage.ru_utime.tv_usec
 
   97      logFile << 
"CPU Time Used (system): " << usage.ru_stime.tv_sec << 
"s " 
   98              << usage.ru_stime.tv_usec << 
"us\n";
 
   99      logFile << 
"Max Resident Set Size: " << usage.ru_maxrss << 
" KB\n";
 
  104  static void handleSignal(
int signal, siginfo_t* info, 
void* context)
 
  106    const char* signalName = 
nullptr;
 
  110        signalName = 
"SIGABRT";
 
  113        signalName = 
"SIGSEGV";
 
  116        signalName = 
"Unknown";
 
  120    std::string logDir = std::string(std::getenv(
"HOME")) + 
"/.cache/inLimbo/";
 
  121    createCacheDirectory(logDir); 
 
  123    std::string   logFileName = logDir + 
"debug-" + std::to_string(signal) + 
".log";
 
  124    std::ofstream logFile(logFileName, std::ios::out | std::ios::app);
 
  126    if (logFile.is_open())
 
  128      logFile << 
"=== Signal Caught ===\n";
 
  129      logFile << 
"Timestamp: " << getCurrentTimestamp() << 
"\n";
 
  130      logFile << 
"Signal: " << signalName << 
" (" << signal << 
")\n";
 
  133        logFile << 
"Address causing signal: " << info->si_addr << 
"\n";
 
  137      logSystemInfo(logFile);
 
  141      int   size = backtrace(buffer, 128);
 
  142      logFile << 
"Backtrace (" << size << 
" frames):\n";
 
  143      char** symbols = backtrace_symbols(buffer, size);
 
  144      for (
int i = 0; i < size; ++i)
 
  146        logFile << symbols[i] << 
'\n';
 
  152      std::cerr << 
"** Critical error occurred. See " << logFileName << 
" for details.**\n" 
  153                << 
"Exiting..." << std::endl;
 
  157      std::cerr << 
"-- Failed to write to log file: " << logFileName << 
"\n";