1 /* 2 * Copyright 2023, Trung Nguyen, trungnt282910@gmail.com. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <stdio.h> 8 9 #include <string> 10 11 #include "signals.h" 12 13 14 // signal names 15 static const char *kSignalName[] = { 16 /* 0 */ "SIG0", 17 /* 1 */ "SIGHUP", 18 /* 2 */ "SIGINT", 19 /* 3 */ "SIGQUIT", 20 /* 4 */ "SIGILL", 21 /* 5 */ "SIGCHLD", 22 /* 6 */ "SIGABRT", 23 /* 7 */ "SIGPIPE", 24 /* 8 */ "SIGFPE", 25 /* 9 */ "SIGKILL", 26 /* 10 */ "SIGSTOP", 27 /* 11 */ "SIGSEGV", 28 /* 12 */ "SIGCONT", 29 /* 13 */ "SIGTSTP", 30 /* 14 */ "SIGALRM", 31 /* 15 */ "SIGTERM", 32 /* 16 */ "SIGTTIN", 33 /* 17 */ "SIGTTOU", 34 /* 18 */ "SIGUSR1", 35 /* 19 */ "SIGUSR2", 36 /* 20 */ "SIGWINCH", 37 /* 21 */ "SIGKILLTHR", 38 /* 22 */ "SIGTRAP", 39 /* 23 */ "SIGPOLL", 40 /* 24 */ "SIGPROF", 41 /* 25 */ "SIGSYS", 42 /* 26 */ "SIGURG", 43 /* 27 */ "SIGVTALRM", 44 /* 28 */ "SIGXCPU", 45 /* 29 */ "SIGXFSZ", 46 /* 30 */ "SIGBUS", 47 /* 31 */ "SIGRESERVED1", 48 /* 32 */ "SIGRESERVED2", 49 }; 50 51 52 std::string 53 signal_name(int signal) 54 { 55 if (signal >= 0 && signal <= SIGRESERVED2) 56 return kSignalName[signal]; 57 58 static char buffer[32]; 59 sprintf(buffer, "%d", signal); 60 return buffer; 61 } 62 63 64 static const char * 65 signal_code(int signal, int code) 66 { 67 #define CASE(X) case X: return #X; 68 switch (code) { 69 CASE(SI_USER) 70 CASE(SI_QUEUE) 71 CASE(SI_TIMER) 72 CASE(SI_ASYNCIO) 73 CASE(SI_MESGQ) 74 } 75 76 switch (signal) { 77 case SIGILL: 78 switch (code) { 79 CASE(ILL_ILLOPC) 80 CASE(ILL_ILLOPN) 81 CASE(ILL_ILLADR) 82 CASE(ILL_ILLTRP) 83 CASE(ILL_PRVOPC) 84 CASE(ILL_PRVREG) 85 CASE(ILL_COPROC) 86 CASE(ILL_BADSTK) 87 } 88 break; 89 case SIGFPE: 90 switch (code) { 91 CASE(FPE_INTDIV) 92 CASE(FPE_INTOVF) 93 CASE(FPE_FLTDIV) 94 CASE(FPE_FLTOVF) 95 CASE(FPE_FLTUND) 96 CASE(FPE_FLTRES) 97 CASE(FPE_FLTINV) 98 CASE(FPE_FLTSUB) 99 } 100 break; 101 case SIGSEGV: 102 switch (code) { 103 CASE(SEGV_MAPERR) 104 CASE(SEGV_ACCERR) 105 } 106 break; 107 case SIGBUS: 108 switch (code) { 109 CASE(BUS_ADRALN) 110 CASE(BUS_ADRERR) 111 CASE(BUS_OBJERR) 112 } 113 break; 114 case SIGTRAP: 115 switch (code) { 116 CASE(TRAP_BRKPT) 117 CASE(TRAP_TRACE) 118 } 119 break; 120 case SIGCHLD: 121 switch (code) { 122 CASE(CLD_EXITED) 123 CASE(CLD_KILLED) 124 CASE(CLD_DUMPED) 125 CASE(CLD_TRAPPED) 126 CASE(CLD_STOPPED) 127 CASE(CLD_CONTINUED) 128 } 129 break; 130 case SIGPOLL: 131 switch (code) { 132 CASE(POLL_IN) 133 CASE(POLL_OUT) 134 CASE(POLL_MSG) 135 CASE(POLL_ERR) 136 CASE(POLL_PRI) 137 CASE(POLL_HUP) 138 } 139 break; 140 } 141 #undef CASE 142 143 static char buffer[32]; 144 sprintf(buffer, "%d", code); 145 return buffer; 146 } 147 148 149 std::string 150 signal_info(siginfo_t& info) 151 { 152 static char buffer[32]; 153 std::string string; 154 155 string.reserve(256); 156 157 string += "{"; 158 string += "si_signo="; 159 string += signal_name(info.si_signo); 160 string += ", si_code="; 161 string += signal_code(info.si_signo, info.si_code); 162 163 if (info.si_errno != 0) { 164 string += ", si_errno=0x"; 165 sprintf(buffer, "%x", info.si_errno); 166 string += buffer; 167 } 168 169 string += ", si_pid="; 170 sprintf(buffer, "%d", (int)info.si_pid); 171 string += buffer; 172 string += ", si_uid="; 173 sprintf(buffer, "%d", (int)info.si_uid); 174 string += buffer; 175 176 if (info.si_signo == SIGILL || info.si_signo == SIGFPE || info.si_signo == SIGSEGV 177 || info.si_signo == SIGBUS || info.si_signo == SIGTRAP) { 178 string += ", si_addr="; 179 sprintf(buffer, "%p", info.si_addr); 180 string += buffer; 181 } 182 183 if (info.si_signo == SIGCHLD) { 184 string += ", si_status="; 185 sprintf(buffer, "%d", info.si_status); 186 string += buffer; 187 } 188 189 if (info.si_signo == SIGPOLL) { 190 string += ", si_band="; 191 sprintf(buffer, "%ld", info.si_band); 192 string += buffer; 193 } 194 195 string += ", si_value="; 196 sprintf(buffer, "%p", info.si_value.sival_ptr); 197 string += buffer; 198 string += "}"; 199 200 return string; 201 } 202