]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/syscallfmt.c
kernel: fix sysexec() error handling compiler problem, sysrendez() busyloop
[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         t[n] = 0;
26         for(i = 0; i < n; i++)
27                 if(a[i] > 0x20 && a[i] < 0x7f)  /* printable ascii? */
28                         t[i] = a[i];
29                 else
30                         t[i] = '.';
31
32         fmtprint(f, " %#p/\"%s\"%s", a, t, suffix);
33         free(t);
34 }
35
36 static void
37 fmtuserstring(Fmt* f, char* a, char* suffix)
38 {
39         int n;
40         char *t;
41
42         if(a == nil){
43                 fmtprint(f, "0/\"\"%s", suffix);
44                 return;
45         }
46         validaddr((ulong)a, 1, 0);
47         n = ((char*)vmemchr(a, 0, 0x7fffffff) - a) + 1;
48         t = smalloc(n+1);
49         memmove(t, a, n);
50         t[n] = 0;
51         fmtprint(f, "%#p/\"%s\"%s", a, t, suffix);
52         free(t);
53 }
54
55 void
56 syscallfmt(ulong syscallno, ulong pc, va_list list)
57 {
58         long l;
59         Fmt fmt;
60         void *v;
61         vlong vl;
62         uintptr p;
63         int i[2], len;
64         char *a, **argv;
65
66         fmtstrinit(&fmt);
67         fmtprint(&fmt, "%uld %s ", up->pid, up->text);
68
69         if(syscallno >= nsyscall)
70                 fmtprint(&fmt, " %uld ", syscallno);
71         else
72                 fmtprint(&fmt, "%s ", sysctab[syscallno]?
73                         sysctab[syscallno]: "huh?");
74
75         fmtprint(&fmt, "%ulx ", pc);
76         switch(syscallno){
77         case SYSR1:
78                 p = va_arg(list, uintptr);
79                 fmtprint(&fmt, "%#p", p);
80                 break;
81         case _ERRSTR:                                   /* deprecated */
82         case CHDIR:
83         case EXITS:
84         case REMOVE:
85                 a = va_arg(list, char*);
86                 fmtuserstring(&fmt, a, "");
87                 break;
88         case BIND:
89                 a = va_arg(list, char*);
90                 fmtuserstring(&fmt, a, " ");
91                 a = va_arg(list, char*);
92                 fmtuserstring(&fmt, a, " ");
93                 i[0] = va_arg(list, int);
94                 fmtprint(&fmt, "%#ux",  i[0]);
95                 break;
96         case CLOSE:
97         case NOTED:
98                 i[0] = va_arg(list, int);
99                 fmtprint(&fmt, "%d", i[0]);
100                 break;
101         case DUP:
102                 i[0] = va_arg(list, int);
103                 i[1] = va_arg(list, int);
104                 fmtprint(&fmt, "%d %d", i[0], i[1]);
105                 break;
106         case ALARM:
107                 l = va_arg(list, unsigned long);
108                 fmtprint(&fmt, "%#lud ", l);
109                 break;
110         case EXEC:
111                 a = va_arg(list, char*);
112                 fmtuserstring(&fmt, a, "");
113                 argv = va_arg(list, char**);
114                 evenaddr(PTR2UINT(argv));
115                 for(;;){
116                         validaddr((ulong)argv, sizeof(char**), 0);
117                         a = *(char **)argv;
118                         if(a == nil)
119                                 break;
120                         fmtprint(&fmt, " ");
121                         fmtuserstring(&fmt, a, "");
122                         argv++;
123                 }
124                 break;
125         case _FSESSION:                                 /* deprecated */
126         case _FSTAT:                                    /* deprecated */
127         case _FWSTAT:                                   /* obsolete */
128                 i[0] = va_arg(list, int);
129                 a = va_arg(list, char*);
130                 fmtprint(&fmt, "%d %#p", i[0], a);
131                 break;
132         case FAUTH:
133                 i[0] = va_arg(list, int);
134                 a = va_arg(list, char*);
135                 fmtprint(&fmt, "%d", i[0]);
136                 fmtuserstring(&fmt, a, "");
137                 break;
138         case SEGBRK:
139         case RENDEZVOUS:
140                 v = va_arg(list, void*);
141                 fmtprint(&fmt, "%#p ", v);
142                 v = va_arg(list, void*);
143                 fmtprint(&fmt, "%#p", v);
144                 break;
145         case _MOUNT:                                    /* deprecated */
146                 i[0] = va_arg(list, int);
147                 fmtprint(&fmt, "%d ", i[0]);
148                 a = va_arg(list, char*);
149                 fmtuserstring(&fmt, a, " ");
150                 i[0] = va_arg(list, int);
151                 fmtprint(&fmt, "%#ux ", i[0]);
152                 a = va_arg(list, char*);
153                 fmtuserstring(&fmt, a, "");
154                 break;
155         case OPEN:
156                 a = va_arg(list, char*);
157                 fmtuserstring(&fmt, a, " ");
158                 i[0] = va_arg(list, int);
159                 fmtprint(&fmt, "%#ux", i[0]);
160                 break;
161         case OSEEK:                                     /* deprecated */
162                 i[0] = va_arg(list, int);
163                 l = va_arg(list, long);
164                 i[1] = va_arg(list, int);
165                 fmtprint(&fmt, "%d %ld %d", i[0], l, i[1]);
166                 break;
167         case SLEEP:
168                 l = va_arg(list, long);
169                 fmtprint(&fmt, "%ld", l);
170                 break;
171         case _STAT:                                     /* obsolete */
172         case _WSTAT:                                    /* obsolete */
173                 a = va_arg(list, char*);
174                 fmtuserstring(&fmt, a, " ");
175                 a = va_arg(list, char*);
176                 fmtprint(&fmt, "%#p", a);
177                 break;
178         case RFORK:
179                 i[0] = va_arg(list, int);
180                 fmtprint(&fmt, "%#ux", i[0]);
181                 break;
182         case PIPE:
183         case BRK_:
184                 v = va_arg(list, int*);
185                 fmtprint(&fmt, "%#p", v);
186                 break;
187         case CREATE:
188                 a = va_arg(list, char*);
189                 fmtuserstring(&fmt, a, " ");
190                 i[0] = va_arg(list, int);
191                 i[1] = va_arg(list, int);
192                 fmtprint(&fmt, "%#ux %#ux", i[0], i[1]);
193                 break;
194         case FD2PATH:
195         case FSTAT:
196         case FWSTAT:
197                 i[0] = va_arg(list, int);
198                 a = va_arg(list, char*);
199                 l = va_arg(list, unsigned long);
200                 fmtprint(&fmt, "%d %#p %lud", i[0], a, l);
201                 break;
202         case NOTIFY:
203         case SEGDETACH:
204         case _WAIT:                                     /* deprecated */
205                 v = va_arg(list, void*);
206                 fmtprint(&fmt, "%#p", v);
207                 break;
208         case SEGATTACH:
209                 i[0] = va_arg(list, int);
210                 fmtprint(&fmt, "%d ", i[0]);
211                 a = va_arg(list, char*);
212                 fmtuserstring(&fmt, a, " ");
213                 /*FALLTHROUGH*/
214         case SEGFREE:
215         case SEGFLUSH:
216                 v = va_arg(list, void*);
217                 l = va_arg(list, unsigned long);
218                 fmtprint(&fmt, "%#p %lud", v, l);
219                 break;
220         case UNMOUNT:
221                 a = va_arg(list, char*);
222                 fmtuserstring(&fmt, a, " ");
223                 a = va_arg(list, char*);
224                 fmtuserstring(&fmt, a, "");
225                 break;
226         case SEMACQUIRE:
227         case SEMRELEASE:
228                 v = va_arg(list, int*);
229                 i[0] = va_arg(list, int);
230                 fmtprint(&fmt, "%#p %d", v, i[0]);
231                 break;
232         case TSEMACQUIRE:
233                 v = va_arg(list, int*);
234                 l = va_arg(list, ulong);
235                 fmtprint(&fmt, "%#p %ld", v, l);
236                 break;
237         case SEEK:
238                 v = va_arg(list, vlong*);
239                 i[0] = va_arg(list, int);
240                 vl = va_arg(list, vlong);
241                 i[1] = va_arg(list, int);
242                 fmtprint(&fmt, "%#p %d %#llux %d", v, i[0], vl, i[1]);
243                 break;
244         case FVERSION:
245                 i[0] = va_arg(list, int);
246                 i[1] = va_arg(list, int);
247                 fmtprint(&fmt, "%d %d ", i[0], i[1]);
248                 a = va_arg(list, char*);
249                 fmtuserstring(&fmt, a, " ");
250                 l = va_arg(list, unsigned long);
251                 fmtprint(&fmt, "%lud", l);
252                 break;
253         case WSTAT:
254         case STAT:
255                 a = va_arg(list, char*);
256                 fmtuserstring(&fmt, a, " ");
257                 /*FALLTHROUGH*/
258         case ERRSTR:
259         case AWAIT:
260                 a = va_arg(list, char*);
261                 l = va_arg(list, unsigned long);
262                 fmtprint(&fmt, "%#p %lud", a, l);
263                 break;
264         case MOUNT:
265                 i[0] = va_arg(list, int);
266                 i[1] = va_arg(list, int);
267                 fmtprint(&fmt, "%d %d ", i[0], i[1]);
268                 a = va_arg(list, char*);
269                 fmtuserstring(&fmt, a, " ");
270                 i[0] = va_arg(list, int);
271                 fmtprint(&fmt, "%#ux ", i[0]);
272                 a = va_arg(list, char*);
273                 fmtuserstring(&fmt, a, "");
274                 break;
275         case _READ:                                     /* deprecated */
276         case PREAD:
277                 i[0] = va_arg(list, int);
278                 v = va_arg(list, void*);
279                 l = va_arg(list, long);
280                 fmtprint(&fmt, "%d %#p %ld", i[0], v, l);
281                 if(syscallno == PREAD){
282                         vl = va_arg(list, vlong);
283                         fmtprint(&fmt, " %lld", vl);
284                 }
285                 break;
286         case _WRITE:                                    /* deprecated */
287         case PWRITE:
288                 i[0] = va_arg(list, int);
289                 v = va_arg(list, void*);
290                 l = va_arg(list, long);
291                 fmtprint(&fmt, "%d ", i[0]);
292                 len = MIN(l, 64);
293                 fmtrwdata(&fmt, v, len, " ");
294                 fmtprint(&fmt, "%ld", l);
295                 if(syscallno == PWRITE){
296                         vl = va_arg(list, vlong);
297                         fmtprint(&fmt, " %lld", vl);
298                 }
299                 break;
300         }
301
302         a = fmtstrflush(&fmt);
303         qlock(&up->debug);
304         free(up->syscalltrace);
305         up->syscalltrace = a;
306         qunlock(&up->debug);
307 }
308
309 void
310 sysretfmt(ulong syscallno, va_list list, long ret, uvlong start, uvlong stop)
311 {
312         long l;
313         void* v;
314         Fmt fmt;
315         vlong vl;
316         int i, len;
317         char *a, *errstr;
318
319         fmtstrinit(&fmt);
320
321         errstr = "\"\"";
322         switch(syscallno){
323         default:
324         case ALARM:
325         case _WRITE:
326         case PWRITE:
327                 if(ret == -1)
328                         errstr = up->syserrstr;
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->syserrstr;
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->syserrstr;
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->syserrstr;
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->syserrstr;
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->syserrstr;
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
405         a = fmtstrflush(&fmt);
406         qlock(&up->debug);
407         free(up->syscalltrace);
408         up->syscalltrace = a;
409         qunlock(&up->debug);
410 }