123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- /*
- * Print functions for system call tracing.
- */
- #include "u.h"
- #include "../port/lib.h"
- #include "mem.h"
- #include "dat.h"
- #include "fns.h"
- #include "/sys/src/libc/9syscall/sys.h"
- // WE ARE OVERRUNNING SOMEHOW
- static void
- fmtrwdata(Fmt* f, char* a, int n, char* suffix)
- {
- int i;
- char *t;
- if(a == nil){
- fmtprint(f, "0x0%s", suffix);
- return;
- }
- validaddr((ulong)a, n, 0);
- t = smalloc(n+1);
- for(i = 0; i < n; i++)
- if(a[i] > 0x20 && a[i] < 0x7f) /* printable ascii? */
- t[i] = a[i];
- else
- t[i] = '.';
- fmtprint(f, " %#p/\"%s\"%s", a, t, suffix);
- free(t);
- }
- static void
- fmtuserstring(Fmt* f, char* a, char* suffix)
- {
- int n;
- char *t;
- if(a == nil){
- fmtprint(f, "0/\"\"%s", suffix);
- return;
- }
- validaddr((ulong)a, 1, 0);
- n = ((char*)vmemchr(a, 0, 0x7fffffff) - a) + 1;
- t = smalloc(n+1);
- memmove(t, a, n);
- t[n] = 0;
- fmtprint(f, "%#p/\"%s\"%s", a, t, suffix);
- free(t);
- }
- void
- syscallfmt(int syscallno, ulong pc, va_list list)
- {
- long l;
- Fmt fmt;
- void *v;
- vlong vl;
- uintptr p;
- int i[2], len;
- char *a, **argv;
- fmtstrinit(&fmt);
- fmtprint(&fmt, "%uld %s ", up->pid, up->text);
- if(syscallno > nsyscall)
- fmtprint(&fmt, " %d ", syscallno);
- else
- fmtprint(&fmt, "%s ", sysctab[syscallno]?
- sysctab[syscallno]: "huh?");
- fmtprint(&fmt, "%ulx ", pc);
- if(up->syscalltrace != nil)
- free(up->syscalltrace);
- switch(syscallno){
- case SYSR1:
- p = va_arg(list, uintptr);
- fmtprint(&fmt, "%#p", p);
- break;
- case _ERRSTR: /* deprecated */
- case CHDIR:
- case EXITS:
- case REMOVE:
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, "");
- break;
- case BIND:
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- i[0] = va_arg(list, int);
- fmtprint(&fmt, "%#ux", i[0]);
- break;
- case CLOSE:
- case NOTED:
- i[0] = va_arg(list, int);
- fmtprint(&fmt, "%d", i[0]);
- break;
- case DUP:
- i[0] = va_arg(list, int);
- i[1] = va_arg(list, int);
- fmtprint(&fmt, "%d %d", i[0], i[1]);
- break;
- case ALARM:
- l = va_arg(list, unsigned long);
- fmtprint(&fmt, "%#lud ", l);
- break;
- case EXEC:
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, "");
- argv = va_arg(list, char**);
- validalign(PTR2UINT(argv), sizeof(char*));
- for(;;){
- validaddr((ulong)argv, sizeof(char**), 0);
- a = *(char **)argv;
- if(a == nil)
- break;
- fmtprint(&fmt, " ");
- fmtuserstring(&fmt, a, "");
- argv++;
- }
- break;
- case _FSESSION: /* deprecated */
- case _FSTAT: /* deprecated */
- case _FWSTAT: /* obsolete */
- i[0] = va_arg(list, int);
- a = va_arg(list, char*);
- fmtprint(&fmt, "%d %#p", i[0], a);
- break;
- case FAUTH:
- i[0] = va_arg(list, int);
- a = va_arg(list, char*);
- fmtprint(&fmt, "%d", i[0]);
- fmtuserstring(&fmt, a, "");
- break;
- case SEGBRK:
- case RENDEZVOUS:
- v = va_arg(list, void*);
- fmtprint(&fmt, "%#p ", v);
- v = va_arg(list, void*);
- fmtprint(&fmt, "%#p", v);
- break;
- case _MOUNT: /* deprecated */
- i[0] = va_arg(list, int);
- fmtprint(&fmt, "%d ", i[0]);
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- i[0] = va_arg(list, int);
- fmtprint(&fmt, "%#ux ", i[0]);
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, "");
- break;
- case OPEN:
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- i[0] = va_arg(list, int);
- fmtprint(&fmt, "%#ux", i[0]);
- break;
- case OSEEK: /* deprecated */
- i[0] = va_arg(list, int);
- l = va_arg(list, long);
- i[1] = va_arg(list, int);
- fmtprint(&fmt, "%d %ld %d", i[0], l, i[1]);
- break;
- case SLEEP:
- l = va_arg(list, long);
- fmtprint(&fmt, "%ld", l);
- break;
- case _STAT: /* obsolete */
- case _WSTAT: /* obsolete */
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- a = va_arg(list, char*);
- fmtprint(&fmt, "%#p", a);
- break;
- case RFORK:
- i[0] = va_arg(list, int);
- fmtprint(&fmt, "%#ux", i[0]);
- break;
- case PIPE:
- case BRK_:
- v = va_arg(list, int*);
- fmtprint(&fmt, "%#p", v);
- break;
- case CREATE:
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- i[0] = va_arg(list, int);
- i[1] = va_arg(list, int);
- fmtprint(&fmt, "%#ux %#ux", i[0], i[1]);
- break;
- case FD2PATH:
- case FSTAT:
- case FWSTAT:
- i[0] = va_arg(list, int);
- a = va_arg(list, char*);
- l = va_arg(list, unsigned long);
- fmtprint(&fmt, "%d %#p %lud", i[0], a, l);
- break;
- case NOTIFY:
- case SEGDETACH:
- case _WAIT: /* deprecated */
- v = va_arg(list, void*);
- fmtprint(&fmt, "%#p", v);
- break;
- case SEGATTACH:
- i[0] = va_arg(list, int);
- fmtprint(&fmt, "%d ", i[0]);
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- /*FALLTHROUGH*/
- case SEGFREE:
- case SEGFLUSH:
- v = va_arg(list, void*);
- l = va_arg(list, unsigned long);
- fmtprint(&fmt, "%#p %lud", v, l);
- break;
- case UNMOUNT:
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, "");
- break;
- case SEMACQUIRE:
- case SEMRELEASE:
- v = va_arg(list, int*);
- i[0] = va_arg(list, int);
- fmtprint(&fmt, "%#p %d", v, i[0]);
- break;
- case TSEMACQUIRE:
- v = va_arg(list, long*);
- l = va_arg(list, ulong);
- fmtprint(&fmt, "%#p %ld", v, l);
- break;
- case SEEK:
- v = va_arg(list, vlong*);
- i[0] = va_arg(list, int);
- vl = va_arg(list, vlong);
- i[1] = va_arg(list, int);
- fmtprint(&fmt, "%#p %d %#llux %d", v, i[0], vl, i[1]);
- break;
- case FVERSION:
- i[0] = va_arg(list, int);
- i[1] = va_arg(list, int);
- fmtprint(&fmt, "%d %d ", i[0], i[1]);
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- l = va_arg(list, unsigned long);
- fmtprint(&fmt, "%lud", l);
- break;
- case WSTAT:
- case STAT:
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- /*FALLTHROUGH*/
- case ERRSTR:
- case AWAIT:
- a = va_arg(list, char*);
- l = va_arg(list, unsigned long);
- fmtprint(&fmt, "%#p %lud", a, l);
- break;
- case MOUNT:
- i[0] = va_arg(list, int);
- i[1] = va_arg(list, int);
- fmtprint(&fmt, "%d %d ", i[0], i[1]);
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, " ");
- i[0] = va_arg(list, int);
- fmtprint(&fmt, "%#ux ", i[0]);
- a = va_arg(list, char*);
- fmtuserstring(&fmt, a, "");
- break;
- case _READ: /* deprecated */
- case PREAD:
- i[0] = va_arg(list, int);
- v = va_arg(list, void*);
- l = va_arg(list, long);
- fmtprint(&fmt, "%d %#p %ld", i[0], v, l);
- if(syscallno == PREAD){
- vl = va_arg(list, vlong);
- fmtprint(&fmt, " %lld", vl);
- }
- break;
- case _WRITE: /* deprecated */
- case PWRITE:
- i[0] = va_arg(list, int);
- v = va_arg(list, void*);
- l = va_arg(list, long);
- fmtprint(&fmt, "%d ", i[0]);
- len = MIN(l, 64);
- fmtrwdata(&fmt, v, len, " ");
- fmtprint(&fmt, "%ld", l);
- if(syscallno == PWRITE){
- vl = va_arg(list, vlong);
- fmtprint(&fmt, " %lld", vl);
- }
- break;
- case NSEC:
- v = va_arg(list, vlong*);
- fmtprint(&fmt, "%#p", v);
- break;
- }
- up->syscalltrace = fmtstrflush(&fmt);
- }
- void
- sysretfmt(int syscallno, va_list list, long ret, uvlong start, uvlong stop)
- {
- long l;
- void* v;
- Fmt fmt;
- vlong vl;
- int i, len;
- char *a, *errstr;
- fmtstrinit(&fmt);
- if(up->syscalltrace)
- free(up->syscalltrace);
- errstr = "\"\"";
- switch(syscallno){
- default:
- case ALARM:
- case _WRITE:
- case PWRITE:
- if(ret == -1)
- errstr = up->syserrstr;
- fmtprint(&fmt, " = %ld", ret);
- break;
- case EXEC:
- case SEGBRK:
- case SEGATTACH:
- case RENDEZVOUS:
- if((void *)ret == (void*)-1)
- errstr = up->syserrstr;
- fmtprint(&fmt, " = %#p", (void *)ret);
- break;
- case AWAIT:
- a = va_arg(list, char*);
- l = va_arg(list, unsigned long);
- if(ret > 0){
- fmtuserstring(&fmt, a, " ");
- fmtprint(&fmt, "%lud = %ld", l, ret);
- }
- else{
- fmtprint(&fmt, "%#p/\"\" %lud = %ld", a, l, ret);
- errstr = up->syserrstr;
- }
- break;
- case _ERRSTR:
- case ERRSTR:
- a = va_arg(list, char*);
- if(syscallno == _ERRSTR)
- l = 64;
- else
- l = va_arg(list, unsigned long);
- if(ret > 0){
- fmtuserstring(&fmt, a, " ");
- fmtprint(&fmt, "%lud = %ld", l, ret);
- }
- else{
- fmtprint(&fmt, "\"\" %lud = %ld", l, ret);
- errstr = up->syserrstr;
- }
- break;
- case FD2PATH:
- i = va_arg(list, int);
- USED(i);
- a = va_arg(list, char*);
- l = va_arg(list, unsigned long);
- if(ret > 0){
- fmtuserstring(&fmt, a, " ");
- fmtprint(&fmt, "%lud = %ld", l, ret);
- }
- else{
- fmtprint(&fmt, "\"\" %lud = %ld", l, ret);
- errstr = up->syserrstr;
- }
- break;
- case _READ:
- case PREAD:
- i = va_arg(list, int);
- USED(i);
- v = va_arg(list, void*);
- l = va_arg(list, long);
- if(ret > 0){
- len = MIN(ret, 64);
- fmtrwdata(&fmt, v, len, "");
- }
- else{
- fmtprint(&fmt, "/\"\"");
- errstr = up->syserrstr;
- }
- fmtprint(&fmt, " %ld", l);
- if(syscallno == PREAD){
- vl = va_arg(list, vlong);
- fmtprint(&fmt, " %lld", vl);
- }
- fmtprint(&fmt, " = %ld", ret);
- break;
- case NSEC:
- fmtprint(&fmt, " = %ld", ret); /* FoV */
- break;
- }
- fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop);
- up->syscalltrace = fmtstrflush(&fmt);
- }
|