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