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 TSEMACQUIRE: 235 v = va_arg(list, long*); 236 l = va_arg(list, ulong); 237 fmtprint(&fmt, "%#p %ld", v, l); 238 break; 239 case SEEK: 240 v = va_arg(list, vlong*); 241 i[0] = va_arg(list, int); 242 vl = va_arg(list, vlong); 243 i[1] = va_arg(list, int); 244 fmtprint(&fmt, "%#p %d %#llux %d", v, i[0], vl, i[1]); 245 break; 246 case FVERSION: 247 i[0] = va_arg(list, int); 248 i[1] = va_arg(list, int); 249 fmtprint(&fmt, "%d %d ", i[0], i[1]); 250 a = va_arg(list, char*); 251 fmtuserstring(&fmt, a, " "); 252 l = va_arg(list, unsigned long); 253 fmtprint(&fmt, "%lud", l); 254 break; 255 case WSTAT: 256 case STAT: 257 a = va_arg(list, char*); 258 fmtuserstring(&fmt, a, " "); 259 /*FALLTHROUGH*/ 260 case ERRSTR: 261 case AWAIT: 262 a = va_arg(list, char*); 263 l = va_arg(list, unsigned long); 264 fmtprint(&fmt, "%#p %lud", a, l); 265 break; 266 case MOUNT: 267 i[0] = va_arg(list, int); 268 i[1] = va_arg(list, int); 269 fmtprint(&fmt, "%d %d ", i[0], i[1]); 270 a = va_arg(list, char*); 271 fmtuserstring(&fmt, a, " "); 272 i[0] = va_arg(list, int); 273 fmtprint(&fmt, "%#ux ", i[0]); 274 a = va_arg(list, char*); 275 fmtuserstring(&fmt, a, ""); 276 break; 277 case _READ: /* deprecated */ 278 case PREAD: 279 i[0] = va_arg(list, int); 280 v = va_arg(list, void*); 281 l = va_arg(list, long); 282 fmtprint(&fmt, "%d %#p %ld", i[0], v, l); 283 if(syscallno == PREAD){ 284 vl = va_arg(list, vlong); 285 fmtprint(&fmt, " %lld", vl); 286 } 287 break; 288 case _WRITE: /* deprecated */ 289 case PWRITE: 290 i[0] = va_arg(list, int); 291 v = va_arg(list, void*); 292 l = va_arg(list, long); 293 fmtprint(&fmt, "%d ", i[0]); 294 len = MIN(l, 64); 295 fmtrwdata(&fmt, v, len, " "); 296 fmtprint(&fmt, "%ld", l); 297 if(syscallno == PWRITE){ 298 vl = va_arg(list, vlong); 299 fmtprint(&fmt, " %lld", vl); 300 } 301 break; 302 } 303 304 up->syscalltrace = fmtstrflush(&fmt); 305 } 306 307 void 308 sysretfmt(int syscallno, va_list list, long ret, uvlong start, uvlong stop) 309 { 310 long l; 311 void* v; 312 Fmt fmt; 313 vlong vl; 314 int i, len; 315 char *a, *errstr; 316 317 fmtstrinit(&fmt); 318 319 if(up->syscalltrace) 320 free(up->syscalltrace); 321 322 errstr = "\"\""; 323 switch(syscallno){ 324 default: 325 case ALARM: 326 case _WRITE: 327 case PWRITE: 328 if(ret == -1) 329 errstr = up->syserrstr; 330 fmtprint(&fmt, " = %ld", ret); 331 break; 332 case EXEC: 333 case SEGBRK: 334 case SEGATTACH: 335 case RENDEZVOUS: 336 if((void *)ret == (void*)-1) 337 errstr = up->syserrstr; 338 fmtprint(&fmt, " = %#p", (void *)ret); 339 break; 340 case AWAIT: 341 a = va_arg(list, char*); 342 l = va_arg(list, unsigned long); 343 if(ret > 0){ 344 fmtuserstring(&fmt, a, " "); 345 fmtprint(&fmt, "%lud = %ld", l, ret); 346 } 347 else{ 348 fmtprint(&fmt, "%#p/\"\" %lud = %ld", a, l, ret); 349 errstr = up->syserrstr; 350 } 351 break; 352 case _ERRSTR: 353 case ERRSTR: 354 a = va_arg(list, char*); 355 if(syscallno == _ERRSTR) 356 l = 64; 357 else 358 l = va_arg(list, unsigned long); 359 if(ret > 0){ 360 fmtuserstring(&fmt, a, " "); 361 fmtprint(&fmt, "%lud = %ld", l, ret); 362 } 363 else{ 364 fmtprint(&fmt, "\"\" %lud = %ld", l, ret); 365 errstr = up->syserrstr; 366 } 367 break; 368 case FD2PATH: 369 i = va_arg(list, int); 370 USED(i); 371 a = va_arg(list, char*); 372 l = va_arg(list, unsigned long); 373 if(ret > 0){ 374 fmtuserstring(&fmt, a, " "); 375 fmtprint(&fmt, "%lud = %ld", l, ret); 376 } 377 else{ 378 fmtprint(&fmt, "\"\" %lud = %ld", l, ret); 379 errstr = up->syserrstr; 380 } 381 break; 382 case _READ: 383 case PREAD: 384 i = va_arg(list, int); 385 USED(i); 386 v = va_arg(list, void*); 387 l = va_arg(list, long); 388 if(ret > 0){ 389 len = MIN(ret, 64); 390 fmtrwdata(&fmt, v, len, ""); 391 } 392 else{ 393 fmtprint(&fmt, "/\"\""); 394 errstr = up->syserrstr; 395 } 396 fmtprint(&fmt, " %ld", l); 397 if(syscallno == PREAD){ 398 vl = va_arg(list, vlong); 399 fmtprint(&fmt, " %lld", vl); 400 } 401 fmtprint(&fmt, " = %ld", ret); 402 break; 403 } 404 fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop); 405 up->syscalltrace = fmtstrflush(&fmt); 406 } 407