inLimbo
TUI Music Player that keeps you in Limbo.
 
Loading...
Searching...
No Matches
signalHandler.hpp
Go to the documentation of this file.
1#ifndef SIGNAL_HANDLER_HPP
2#define SIGNAL_HANDLER_HPP
3
4#include <iostream>
5#include <csignal>
6#include <execinfo.h>
7#include <cstdlib>
8#include <unistd.h>
9#include <fstream>
10#include <string>
11#include <filesystem>
12#include <ctime> // For timestamps
13#include <sys/resource.h> // For resource usage
14#include <sys/utsname.h> // For system info
15#include <pthread.h> // For thread info
16#include <unistd.h> // For getpid, getppid
17#include <limits.h> // For PATH_MAX
18
19class SignalHandler {
20public:
21 // Singleton instance getter
22 static SignalHandler& getInstance() {
23 static SignalHandler instance;
24 return instance;
25 }
26
27 // Initialize the signal handler
28 void setup() {
29 struct sigaction sa;
30 sa.sa_sigaction = SignalHandler::handleSignal; // Use static member function
31 sigemptyset(&sa.sa_mask);
32 sa.sa_flags = SA_SIGINFO; // Use siginfo_t for extended info
33
34 sigaction(SIGABRT, &sa, nullptr); // Catch SIGABRT
35 sigaction(SIGSEGV, &sa, nullptr); // Catch SIGSEGV
36 }
37
38private:
39 SignalHandler() = default; // Private constructor for singleton
40 ~SignalHandler() = default;
41
42 // Non-copyable and non-movable
43 SignalHandler(const SignalHandler&) = delete;
44 SignalHandler& operator=(const SignalHandler&) = delete;
45
46 // Get current timestamp as a string
47 static std::string getCurrentTimestamp() {
48 std::time_t now = std::time(nullptr);
49 char buffer[100];
50 std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
51 return std::string(buffer);
52 }
53
54 static void createCacheDirectory(const std::string& path) {
55 struct stat info;
56 if (stat(path.c_str(), &info) != 0 || !(info.st_mode & S_IFDIR)) {
57 mkdir(path.c_str(), 0755); // Create directory with rwx permissions
58 }
59 }
60
61 // Get system and environment details
62 static void logSystemInfo(std::ofstream& logFile) {
63 // Process and thread information
64 logFile << "Process ID: " << getpid() << "\n";
65 logFile << "Parent Process ID: " << getppid() << "\n";
66 logFile << "Thread ID: " << pthread_self() << "\n";
67
68 // Current working directory
69 char cwd[PATH_MAX];
70 if (getcwd(cwd, sizeof(cwd))) {
71 logFile << "Current Working Directory: " << cwd << "\n";
72 }
73
74 // System information
75 struct utsname sysInfo;
76 if (uname(&sysInfo) == 0) {
77 logFile << "System Name: " << sysInfo.sysname << "\n";
78 logFile << "Node Name: " << sysInfo.nodename << "\n";
79 logFile << "Release: " << sysInfo.release << "\n";
80 logFile << "Version: " << sysInfo.version << "\n";
81 logFile << "Machine: " << sysInfo.machine << "\n";
82 }
83
84 // Resource usage
85 struct rusage usage;
86 if (getrusage(RUSAGE_SELF, &usage) == 0) {
87 logFile << "CPU Time Used (user): " << usage.ru_utime.tv_sec << "s " << usage.ru_utime.tv_usec << "us\n";
88 logFile << "CPU Time Used (system): " << usage.ru_stime.tv_sec << "s " << usage.ru_stime.tv_usec << "us\n";
89 logFile << "Max Resident Set Size: " << usage.ru_maxrss << " KB\n";
90 }
91 }
92
93 // Signal handling function
94 static void handleSignal(int signal, siginfo_t* info, void* context) {
95 const char* signalName = nullptr;
96 switch (signal) {
97 case SIGABRT: signalName = "SIGABRT"; break;
98 case SIGSEGV: signalName = "SIGSEGV"; break;
99 default: signalName = "Unknown"; break;
100 }
101
102 std::string logDir = std::string(std::getenv("HOME")) + "/.cache/inLimbo/";
103 createCacheDirectory(logDir); // Ensure the directory exists
104
105 std::string logFileName = logDir +"debug-" + std::to_string(signal) + ".log";
106 std::ofstream logFile(logFileName, std::ios::out | std::ios::app);
107
108 if (logFile.is_open()) {
109 logFile << "=== Signal Caught ===\n";
110 logFile << "Timestamp: " << getCurrentTimestamp() << "\n";
111 logFile << "Signal: " << signalName << " (" << signal << ")\n";
112 if (info) {
113 logFile << "Address causing signal: " << info->si_addr << "\n";
114 }
115
116 // Log system and environment information
117 logSystemInfo(logFile);
118
119 // Generate a backtrace
120 void* buffer[128];
121 int size = backtrace(buffer, 128);
122 logFile << "Backtrace (" << size << " frames):\n";
123 char** symbols = backtrace_symbols(buffer, size);
124 for (int i = 0; i < size; ++i) {
125 logFile << symbols[i] << '\n';
126 }
127 free(symbols);
128
129 logFile.close();
130
131 std::cerr << "Critical error occurred. See " << logFileName << " for details.\n" << "Exiting..." << std::endl;
132 } else {
133 std::cerr << "Failed to write to log file: " << logFileName << "\n";
134 }
135
136 // Clean termination
137 _Exit(EXIT_FAILURE);
138 }
139};
140
141#endif
Definition signalHandler.hpp:19
void setup()
Definition signalHandler.hpp:28
static SignalHandler & getInstance()
Definition signalHandler.hpp:22