]> granicus.if.org Git - strace/blob - printsiginfo.c
tests: rewrite umovestr2.test without using grep
[strace] / printsiginfo.c
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 }