diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/9/port/syscallfmt.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/9/port/syscallfmt.c')
-rwxr-xr-x | sys/src/9/port/syscallfmt.c | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/sys/src/9/port/syscallfmt.c b/sys/src/9/port/syscallfmt.c new file mode 100755 index 000000000..c04cc5cf8 --- /dev/null +++ b/sys/src/9/port/syscallfmt.c @@ -0,0 +1,405 @@ +/* + * 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**); + evenaddr(PTR2UINT(argv)); + 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 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; + } + + 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: + if(ret == -1) + errstr = up->errstr; + fmtprint(&fmt, " = %ld", ret); + break; + case ALARM: + case _WRITE: + case PWRITE: + if(ret == -1) + errstr = up->errstr; + fmtprint(&fmt, " = %ld", ret); + break; + case EXEC: + case SEGBRK: + case SEGATTACH: + case RENDEZVOUS: + if((void *)ret == (void*)-1) + errstr = up->errstr; + 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->errstr; + } + 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->errstr; + } + 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->errstr; + } + 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->errstr; + } + fmtprint(&fmt, " %ld", l); + if(syscallno == PREAD){ + vl = va_arg(list, vlong); + fmtprint(&fmt, " %lld", vl); + } + fmtprint(&fmt, " = %ld", ret); + break; + } + fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop); + up->syscalltrace = fmtstrflush(&fmt); +} |