printsiginfo.c revision 0e946ab2c26f3cb6f27cb99ddf0f5581bef16781
1#include "defs.h" 2 3#include <signal.h> 4 5#include "printsiginfo.h" 6 7#include "xlat/sigbus_codes.h" 8#include "xlat/sigchld_codes.h" 9#include "xlat/sigfpe_codes.h" 10#include "xlat/sigill_codes.h" 11#include "xlat/siginfo_codes.h" 12#include "xlat/sigpoll_codes.h" 13#include "xlat/sigprof_codes.h" 14#include "xlat/sigsegv_codes.h" 15#include "xlat/sigsys_codes.h" 16#include "xlat/sigtrap_codes.h" 17 18#ifdef SIGEMT 19# include "xlat/sigemt_codes.h" 20#endif 21 22#ifndef SI_FROMUSER 23# define SI_FROMUSER(sip) ((sip)->si_code <= 0) 24#endif 25 26static void 27printsigsource(const siginfo_t *sip) 28{ 29 tprintf(", si_pid=%lu, si_uid=%lu", 30 (unsigned long) sip->si_pid, 31 (unsigned long) sip->si_uid); 32} 33 34static void 35printsigval(const siginfo_t *sip, bool verbose) 36{ 37 if (!verbose) 38 tprints(", ..."); 39 else 40 tprintf(", si_value={int=%u, ptr=%#lx}", 41 sip->si_int, 42 (unsigned long) sip->si_ptr); 43} 44 45static void 46print_si_code(int si_signo, int si_code) 47{ 48 const char *code = xlookup(siginfo_codes, si_code); 49 50 if (!code) { 51 switch (si_signo) { 52 case SIGTRAP: 53 code = xlookup(sigtrap_codes, si_code); 54 break; 55 case SIGCHLD: 56 code = xlookup(sigchld_codes, si_code); 57 break; 58 case SIGPOLL: 59 code = xlookup(sigpoll_codes, si_code); 60 break; 61 case SIGPROF: 62 code = xlookup(sigprof_codes, si_code); 63 break; 64 case SIGILL: 65 code = xlookup(sigill_codes, si_code); 66 break; 67#ifdef SIGEMT 68 case SIGEMT: 69 code = xlookup(sigemt_codes, si_code); 70 break; 71#endif 72 case SIGFPE: 73 code = xlookup(sigfpe_codes, si_code); 74 break; 75 case SIGSEGV: 76 code = xlookup(sigsegv_codes, si_code); 77 break; 78 case SIGBUS: 79 code = xlookup(sigbus_codes, si_code); 80 break; 81 case SIGSYS: 82 code = xlookup(sigsys_codes, si_code); 83 break; 84 } 85 } 86 87 if (code) 88 tprints(code); 89 else 90 tprintf("%#x", si_code); 91} 92 93static void 94print_si_info(const siginfo_t *sip, bool verbose) 95{ 96 if (sip->si_errno) { 97 tprints(", si_errno="); 98 if ((unsigned) sip->si_errno < nerrnos 99 && errnoent[sip->si_errno]) 100 tprints(errnoent[sip->si_errno]); 101 else 102 tprintf("%d", sip->si_errno); 103 } 104 105 if (SI_FROMUSER(sip)) { 106 switch (sip->si_code) { 107 case SI_USER: 108 printsigsource(sip); 109 break; 110 case SI_TKILL: 111 printsigsource(sip); 112 break; 113#if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN 114 case SI_TIMER: 115 tprintf(", si_timerid=%#x, si_overrun=%d", 116 sip->si_timerid, sip->si_overrun); 117 printsigval(sip, verbose); 118 break; 119#endif 120 default: 121 printsigsource(sip); 122 if (sip->si_ptr) 123 printsigval(sip, verbose); 124 break; 125 } 126 } else { 127 switch (sip->si_signo) { 128 case SIGCHLD: 129 printsigsource(sip); 130 tprints(", si_status="); 131 if (sip->si_code == CLD_EXITED) 132 tprintf("%d", sip->si_status); 133 else 134 printsignal(sip->si_status); 135 if (!verbose) 136 tprints(", ..."); 137 else 138 tprintf(", si_utime=%llu, si_stime=%llu", 139 (unsigned long long) sip->si_utime, 140 (unsigned long long) sip->si_stime); 141 break; 142 case SIGILL: case SIGFPE: 143 case SIGSEGV: case SIGBUS: 144 tprintf(", si_addr=%#lx", 145 (unsigned long) sip->si_addr); 146 break; 147 case SIGPOLL: 148 switch (sip->si_code) { 149 case POLL_IN: case POLL_OUT: case POLL_MSG: 150 tprintf(", si_band=%ld", 151 (long) sip->si_band); 152 break; 153 } 154 break; 155#ifdef HAVE_SIGINFO_T_SI_SYSCALL 156 case SIGSYS: 157 tprintf(", si_call_addr=%#lx, si_syscall=%d, si_arch=%u", 158 (unsigned long) sip->si_call_addr, 159 sip->si_syscall, sip->si_arch); 160 break; 161#endif 162 default: 163 if (sip->si_pid || sip->si_uid) 164 printsigsource(sip); 165 if (sip->si_ptr) 166 printsigval(sip, verbose); 167 } 168 } 169} 170 171void 172printsiginfo(const siginfo_t *sip, bool verbose) 173{ 174 if (sip->si_signo == 0) { 175 tprints("{}"); 176 return; 177 } 178 tprints("{si_signo="); 179 printsignal(sip->si_signo); 180 181 tprints(", si_code="); 182 print_si_code(sip->si_signo, sip->si_code); 183 184#ifdef SI_NOINFO 185 if (sip->si_code != SI_NOINFO) 186#endif 187 print_si_info(sip, verbose); 188 189 tprints("}"); 190} 191 192void 193printsiginfo_at(struct tcb *tcp, long addr) 194{ 195 siginfo_t si; 196 197 if (!umove_or_printaddr(tcp, addr, &si)) 198 printsiginfo(&si, verbose(tcp)); 199} 200