]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/syscallfmt.c
devshr: fixed crash
[plan9front.git] / sys / src / 9 / port / syscallfmt.c
1 /*
2  * Print functions for system call tracing.
3  */
4 #include "u.h"
5 #include "../port/lib.h"
6 #include "mem.h"
7 #include "dat.h"
8 #include "fns.h"
9
10 #include "/sys/src/libc/9syscall/sys.h"
11
12 // WE ARE OVERRUNNING SOMEHOW
13 static void
14 fmtrwdata(Fmt* f, char* a, int n, char* suffix)
15 {
16         int i;
17         char *t;
18
19         if(a == nil){
20                 fmtprint(f, "0x0%s", suffix);
21                 return;
22         }
23         validaddr((ulong)a, n, 0);
24         t = smalloc(n+1);
25         for(i = 0; i < n; i++)
26                 if(a[i] > 0x20 && a[i] < 0x7f)  /* printable ascii? */
27                         t[i] = a[i];
28                 else
29                         t[i] = '.';
30
31         fmtprint(f, " %#p/\"%s\"%s", a, t, suffix);
32         free(t);
33 }
34
35 static void
36 fmtuserstring(Fmt* f, char* a, char* suffix)
37 {
38         int n;
39         char *t;
40
41         if(a == nil){
42                 fmtprint(f, "0/\"\"%s", suffix);
43                 return;
44         }
45         validaddr((ulong)a, 1, 0);
46         n = ((char*)vmemchr(a, 0, 0x7fffffff) - a) + 1;
47         t = smalloc(n+1);
48         memmove(t, a, n);
49         t[n] = 0;
50         fmtprint(f, "%#p/\"%s\"%s", a, t, suffix);
51         free(t);
52 }
53
54 void
55 syscallfmt(int syscallno, ulong pc, va_list list)
56 {
57         long l;
58         Fmt fmt;
59         void *v;
60         vlong vl;
61         uintptr p;
62         int i[2], len;
63         char *a, **argv;
64
65         fmtstrinit(&fmt);
66         fmtprint(&fmt, "%uld %s ", up->pid, up->text);
67
68         if(syscallno > nsyscall)
69                 fmtprint(&fmt, " %d ", syscallno);
70         else
71                 fmtprint(&fmt, "%s ", sysctab[syscallno]?
72                         sysctab[syscallno]: "huh?");
73
74         fmtprint(&fmt, "%ulx ", pc);
75         if(up->syscalltrace != nil)
76                 free(up->syscalltrace);
77
78         switch(syscallno){
79         case SYSR1:
80                 p = va_arg(list, uintptr);
81                 fmtprint(&fmt, "%#p", p);
82                 break;
83         case _ERRSTR:                                   /* deprecated */
84         case CHDIR:
85         case EXITS:
86         case REMOVE:
87                 a = va_arg(list, char*);
88                 fmtuserstring(&fmt, a, "");
89                 break;
90         case BIND:
91                 a = va_arg(list, char*);
92                 fmtuserstring(&fmt, a, " ");
93                 a = va_arg(list, char*);
94                 fmtuserstring(&fmt, a, " ");
95                 i[0] = va_arg(list, int);
96                 fmtprint(&fmt, "%#ux",  i[0]);
97                 break;
98         case CLOSE:
99         case NOTED:
100                 i[0] = va_arg(list, int);
101                 fmtprint(&fmt, "%d", i[0]);
102                 break;
103         case DUP:
104                 i[0] = va_arg(list, int);
105                 i[1] = va_arg(list, int);
106                 fmtprint(&fmt, "%d %d", i[0], i[1]);
107                 break;
108         case ALARM:
109                 l = va_arg(list, unsigned long);
110                 fmtprint(&fmt, "%#lud ", l);
111                 break;
112         case EXEC:
113                 a = va_arg(list, char*);
114                 fmtuserstring(&fmt, a, "");
115                 argv = va_arg(list, char**);
116                 evenaddr(PTR2UINT(argv));
117                 for(;;){
118                         validaddr((ulong)argv, sizeof(char**), 0);
119                         a = *(char **)argv;
120                         if(a == nil)
121                                 break;
122                         fmtprint(&fmt, " ");
123                         fmtuserstring(&fmt, a, "");
124                         argv++;
125                 }
126                 break;
127         case _FSESSION:                                 /* deprecated */
128         case _FSTAT:                                    /* deprecated */
129         case _FWSTAT:                                   /* obsolete */
130                 i[0] = va_arg(list, int);
131                 a = va_arg(list, char*);
132                 fmtprint(&fmt, "%d %#p", i[0], a);
133                 break;
134         case FAUTH:
135                 i[0] = va_arg(list, int);
136                 a = va_arg(list, char*);
137                 fmtprint(&fmt, "%d", i[0]);
138                 fmtuserstring(&fmt, a, "");
139                 break;
140         case SEGBRK:
141         case RENDEZVOUS:
142                 v = va_arg(list, void*);
143                 fmtprint(&fmt, "%#p ", v);
144                 v = va_arg(list, void*);
145                 fmtprint(&fmt, "%#p", v);
146                 break;
147         case _MOUNT:                                    /* deprecated */
148                 i[0] = va_arg(list, int);
149                 fmtprint(&fmt, "%d ", i[0]);
150                 a = va_arg(list, char*);
151                 fmtuserstring(&fmt, a, " ");
152                 i[0] = va_arg(list, int);
153                 fmtprint(&fmt, "%#ux ", i[0]);
154                 a = va_arg(list, char*);
155                 fmtuserstring(&fmt, a, "");
156                 break;
157         case OPEN:
158                 a = va_arg(list, char*);
159                 fmtuserstring(&fmt, a, " ");
160                 i[0] = va_arg(list, int);
161                 fmtprint(&fmt, "%#ux", i[0]);
162                 break;
163         case OSEEK:                                     /* deprecated */
164                 i[0] = va_arg(list, int);
165                 l = va_arg(list, long);
166                 i[1] = va_arg(list, int);
167                 fmtprint(&fmt, "%d %ld %d", i[0], l, i[1]);
168                 break;
169         case SLEEP:
170                 l = va_arg(list, long);
171                 fmtprint(&fmt, "%ld", l);
172                 break;
173         case _STAT:                                     /* obsolete */
174         case _WSTAT:                                    /* obsolete */
175                 a = va_arg(list, char*);
176                 fmtuserstring(&fmt, a, " ");
177                 a = va_arg(list, char*);
178                 fmtprint(&fmt, "%#p", a);
179                 break;
180         case RFORK:
181                 i[0] = va_arg(list, int);
182                 fmtprint(&fmt, "%#ux", i[0]);
183                 break;
184         case PIPE:
185         case BRK_:
186                 v = va_arg(list, int*);
187                 fmtprint(&fmt, "%#p", v);
188                 break;
189         case CREATE:
190                 a = va_arg(list, char*);
191                 fmtuserstring(&fmt, a, " ");
192                 i[0] = va_arg(list, int);
193                 i[1] = va_arg(list, int);
194                 fmtprint(&fmt, "%#ux %#ux", i[0], i[1]);
195                 break;
196         case FD2PATH:
197         case FSTAT:
198         case FWSTAT:
199                 i[0] = va_arg(list, int);
200                 a = va_arg(list, char*);
201                 l = va_arg(list, unsigned long);
202                 fmtprint(&fmt, "%d %#p %lud", i[0], a, l);
203                 break;
204         case NOTIFY:
205         case SEGDETACH:
206         case _WAIT:                                     /* deprecated */
207                 v = va_arg(list, void*);
208                 fmtprint(&fmt, "%#p", v);
209                 break;
210         case SEGATTACH:
211                 i[0] = va_arg(list, int);
212                 fmtprint(&fmt, "%d ", i[0]);
213                 a = va_arg(list, char*);
214                 fmtuserstring(&fmt, a, " ");
215                 /*FALLTHROUGH*/
216         case SEGFREE:
217         case SEGFLUSH:
218                 v = va_arg(list, void*);
219                 l = va_arg(list, unsigned long);
220                 fmtprint(&fmt, "%#p %lud", v, l);
221                 break;
222         case UNMOUNT:
223                 a = va_arg(list, char*);
224                 fmtuserstring(&fmt, a, " ");
225                 a = va_arg(list, char*);
226                 fmtuserstring(&fmt, a, "");
227                 break;
228         case SEMACQUIRE:
229         case SEMRELEASE:
230                 v = va_arg(list, int*);
231                 i[0] = va_arg(list, int);
232                 fmtprint(&fmt, "%#p %d", v, i[0]);
233                 break;
234         case SEEK:
235                 v = va_arg(list, vlong*);
236                 i[0] = va_arg(list, int);
237                 vl = va_arg(list, vlong);
238                 i[1] = va_arg(list, int);
239                 fmtprint(&fmt, "%#p %d %#llux %d", v, i[0], vl, i[1]);
240                 break;
241         case FVERSION:
242                 i[0] = va_arg(list, int);
243                 i[1] = va_arg(list, int);
244                 fmtprint(&fmt, "%d %d ", i[0], i[1]);
245                 a = va_arg(list, char*);
246                 fmtuserstring(&fmt, a, " ");
247                 l = va_arg(list, unsigned long);
248                 fmtprint(&fmt, "%lud", l);
249                 break;
250         case WSTAT:
251         case STAT:
252                 a = va_arg(list, char*);
253                 fmtuserstring(&fmt, a, " ");
254                 /*FALLTHROUGH*/
255         case ERRSTR:
256         case AWAIT:
257                 a = va_arg(list, char*);
258                 l = va_arg(list, unsigned long);
259                 fmtprint(&fmt, "%#p %lud", a, l);
260                 break;
261         case MOUNT:
262                 i[0] = va_arg(list, int);
263                 i[1] = va_arg(list, int);
264                 fmtprint(&fmt, "%d %d ", i[0], i[1]);
265                 a = va_arg(list, char*);
266                 fmtuserstring(&fmt, a, " ");
267                 i[0] = va_arg(list, int);
268                 fmtprint(&fmt, "%#ux ", i[0]);
269                 a = va_arg(list, char*);
270                 fmtuserstring(&fmt, a, "");
271                 break;
272         case _READ:                                     /* deprecated */
273         case PREAD:
274                 i[0] = va_arg(list, int);
275                 v = va_arg(list, void*);
276                 l = va_arg(list, long);
277                 fmtprint(&fmt, "%d %#p %ld", i[0], v, l);
278                 if(syscallno == PREAD){
279                         vl = va_arg(list, vlong);
280                         fmtprint(&fmt, " %lld", vl);
281                 }
282                 break;
283         case _WRITE:                                    /* deprecated */
284         case PWRITE:
285                 i[0] = va_arg(list, int);
286                 v = va_arg(list, void*);
287                 l = va_arg(list, long);
288                 fmtprint(&fmt, "%d ", i[0]);
289                 len = MIN(l, 64);
290                 fmtrwdata(&fmt, v, len, " ");
291                 fmtprint(&fmt, "%ld", l);
292                 if(syscallno == PWRITE){
293                         vl = va_arg(list, vlong);
294                         fmtprint(&fmt, " %lld", vl);
295                 }
296                 break;
297         }
298
299         up->syscalltrace = fmtstrflush(&fmt);
300 }
301
302 void
303 sysretfmt(int syscallno, va_list list, long ret, uvlong start, uvlong stop)
304 {
305         long l;
306         void* v;
307         Fmt fmt;
308         vlong vl;
309         int i, len;
310         char *a, *errstr;
311
312         fmtstrinit(&fmt);
313
314         if(up->syscalltrace)
315                 free(up->syscalltrace);
316
317         errstr = "\"\"";
318         switch(syscallno){
319         default:
320                 if(ret == -1)
321                         errstr = up->errstr;
322                 fmtprint(&fmt, " = %ld", ret);
323                 break;
324         case ALARM:
325         case _WRITE:
326         case PWRITE:
327                 if(ret == -1)
328                         errstr = up->errstr;
329                 fmtprint(&fmt, " = %ld", ret);
330                 break;
331         case EXEC:
332         case SEGBRK:
333         case SEGATTACH:
334         case RENDEZVOUS:
335                 if((void *)ret == (void*)-1)
336                         errstr = up->errstr;
337                 fmtprint(&fmt, " = %#p", (void *)ret);
338                 break;
339         case AWAIT:
340                 a = va_arg(list, char*);
341                 l = va_arg(list, unsigned long);
342                 if(ret > 0){
343                         fmtuserstring(&fmt, a, " ");
344                         fmtprint(&fmt, "%lud = %ld", l, ret);
345                 }
346                 else{
347                         fmtprint(&fmt, "%#p/\"\" %lud = %ld", a, l, ret);
348                         errstr = up->errstr;
349                 }
350                 break;
351         case _ERRSTR:
352         case ERRSTR:
353                 a = va_arg(list, char*);
354                 if(syscallno == _ERRSTR)
355                         l = 64;
356                 else
357                         l = va_arg(list, unsigned long);
358                 if(ret > 0){
359                         fmtuserstring(&fmt, a, " ");
360                         fmtprint(&fmt, "%lud = %ld", l, ret);
361                 }
362                 else{
363                         fmtprint(&fmt, "\"\" %lud = %ld", l, ret);
364                         errstr = up->errstr;
365                 }
366                 break;
367         case FD2PATH:
368                 i = va_arg(list, int);
369                 USED(i);
370                 a = va_arg(list, char*);
371                 l = va_arg(list, unsigned long);
372                 if(ret > 0){
373                         fmtuserstring(&fmt, a, " ");
374                         fmtprint(&fmt, "%lud = %ld", l, ret);
375                 }
376                 else{
377                         fmtprint(&fmt, "\"\" %lud = %ld", l, ret);
378                         errstr = up->errstr;
379                 }
380                 break;
381         case _READ:
382         case PREAD:
383                 i = va_arg(list, int);
384                 USED(i);
385                 v = va_arg(list, void*);
386                 l = va_arg(list, long);
387                 if(ret > 0){
388                         len = MIN(ret, 64);
389                         fmtrwdata(&fmt, v, len, "");
390                 }
391                 else{
392                         fmtprint(&fmt, "/\"\"");
393                         errstr = up->errstr;
394                 }
395                 fmtprint(&fmt, " %ld", l);
396                 if(syscallno == PREAD){
397                         vl = va_arg(list, vlong);
398                         fmtprint(&fmt, " %lld", vl);
399                 }
400                 fmtprint(&fmt, " = %ld", ret);
401                 break;
402         }
403         fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop);
404         up->syscalltrace = fmtstrflush(&fmt);
405 }