syscallfmt.c 8.5 KB

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