23 static SignalHandler instance;
30 sa.sa_sigaction = SignalHandler::handleSignal;
31 sigemptyset(&sa.sa_mask);
32 sa.sa_flags = SA_SIGINFO;
34 sigaction(SIGABRT, &sa,
nullptr);
35 sigaction(SIGSEGV, &sa,
nullptr);
47 static std::string getCurrentTimestamp() {
48 std::time_t now = std::time(
nullptr);
50 std::strftime(buffer,
sizeof(buffer),
"%Y-%m-%d %H:%M:%S", std::localtime(&now));
51 return std::string(buffer);
54 static void createCacheDirectory(
const std::string& path) {
56 if (stat(path.c_str(), &info) != 0 || !(info.st_mode & S_IFDIR)) {
57 mkdir(path.c_str(), 0755);
62 static void logSystemInfo(std::ofstream& logFile) {
64 logFile <<
"Process ID: " << getpid() <<
"\n";
65 logFile <<
"Parent Process ID: " << getppid() <<
"\n";
66 logFile <<
"Thread ID: " << pthread_self() <<
"\n";
70 if (getcwd(cwd,
sizeof(cwd))) {
71 logFile <<
"Current Working Directory: " << cwd <<
"\n";
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";
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";
94 static void handleSignal(
int signal, siginfo_t* info,
void* context) {
95 const char* signalName =
nullptr;
97 case SIGABRT: signalName =
"SIGABRT";
break;
98 case SIGSEGV: signalName =
"SIGSEGV";
break;
99 default: signalName =
"Unknown";
break;
102 std::string logDir = std::string(std::getenv(
"HOME")) +
"/.cache/inLimbo/";
103 createCacheDirectory(logDir);
105 std::string logFileName = logDir +
"debug-" + std::to_string(signal) +
".log";
106 std::ofstream logFile(logFileName, std::ios::out | std::ios::app);
108 if (logFile.is_open()) {
109 logFile <<
"=== Signal Caught ===\n";
110 logFile <<
"Timestamp: " << getCurrentTimestamp() <<
"\n";
111 logFile <<
"Signal: " << signalName <<
" (" << signal <<
")\n";
113 logFile <<
"Address causing signal: " << info->si_addr <<
"\n";
117 logSystemInfo(logFile);
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';
131 std::cerr <<
"Critical error occurred. See " << logFileName <<
" for details.\n" <<
"Exiting..." << std::endl;
133 std::cerr <<
"Failed to write to log file: " << logFileName <<
"\n";