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