Home | History | Annotate | Download | only in strace
      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 
     22 static void
     23 printsigsource(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 
     30 static void
     31 printsigval(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 
     41 static void
     42 print_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 
     89 static void
     90 print_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 
    167 void
    168 printsiginfo(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 
    188 void
    189 printsiginfo_at(struct tcb *tcp, long addr)
    190 {
    191 	siginfo_t si;
    192 	if (!addr) {
    193 		tprints("NULL");
    194 		return;
    195 	}
    196 	if (syserror(tcp) || umove(tcp, addr, &si) < 0) {
    197 		tprintf("%#lx", addr);
    198 		return;
    199 	}
    200 	printsiginfo(&si, verbose(tcp));
    201 }
    202