syscallfmt.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "u.h"
  10. #include "../port/lib.h"
  11. #include "mem.h"
  12. #include "dat.h"
  13. #include "fns.h"
  14. #include "sys.h"
  15. /*
  16. * Print functions for system call tracing.
  17. */
  18. static void
  19. fmtrwdata(Fmt* f, char* a, int n, char* suffix)
  20. {
  21. int i;
  22. char *t;
  23. if(a == nil){
  24. fmtprint(f, "0x0%s", suffix);
  25. return;
  26. }
  27. if(!okaddr((uintptr_t)a, n, 0)){
  28. fmtprint(f, "(BAD %p)%s", a, suffix);
  29. return;
  30. }
  31. a = validaddr(a, n, 0);
  32. t = smalloc(n+1);
  33. for(i = 0; i < n; i++){
  34. if(a[i] > 0x20 && a[i] < 0x7f)
  35. t[i] = a[i];
  36. else
  37. t[i] = '.';
  38. }
  39. fmtprint(f, " %#P/\"%s\"%s", a, t, suffix);
  40. free(t);
  41. }
  42. static void
  43. fmtuserstring(Fmt* f, char* a, char* suffix)
  44. {
  45. int len;
  46. char *t;
  47. if(a == nil){
  48. fmtprint(f, "0/\"\"%s", suffix);
  49. return;
  50. }
  51. a = validaddr(a, 1, 0);
  52. len = ((char*)vmemchr(a, 0, 0x7fffffff) - a);
  53. t = smalloc(len+1);
  54. memmove(t, a, len);
  55. t[len] = 0;
  56. fmtprint(f, "%#p/\"%s\"%s", a, t, suffix);
  57. free(t);
  58. }
  59. /*
  60. */
  61. void
  62. syscallfmt(uint8_t what, int syscallno, Ar0 *ar0, uint64_t start, uint64_t stop, ...)
  63. {
  64. Proc *up = externup();
  65. void *errstr = nil;
  66. va_list list;
  67. int32_t l;
  68. uint32_t ul;
  69. Fmt fmt;
  70. void *v;
  71. int64_t vl;
  72. int i[2], len;
  73. char *a, **argv;
  74. va_start(list, stop);
  75. fmtstrinit(&fmt);
  76. fmtprint(&fmt, "%c %d %s ", what, up->pid, up->text);
  77. if(syscallno > nsyscall)
  78. fmtprint(&fmt, " %d ", syscallno);
  79. else
  80. fmtprint(&fmt, "%s ", systab[syscallno].n);
  81. if(up->syscalltrace != nil)
  82. free(up->syscalltrace);
  83. up->syscalltrace = nil;
  84. switch(syscallno){
  85. case SYSR1:
  86. p = va_arg(list, uintptr_t);
  87. fmtprint(&fmt, "%#p", p);
  88. break;
  89. case _ERRSTR: /* deprecated */
  90. case CHDIR:
  91. case EXITS:
  92. case REMOVE:
  93. a = va_arg(list, char*);
  94. fmtuserstring(&fmt, a, "");
  95. break;
  96. case BIND:
  97. a = va_arg(list, char*);
  98. fmtuserstring(&fmt, a, " ");
  99. a = va_arg(list, char*);
  100. fmtuserstring(&fmt, a, " ");
  101. i[0] = va_arg(list, int);
  102. fmtprint(&fmt, "%#x", i[0]);
  103. break;
  104. case CLOSE:
  105. case NOTED:
  106. case SLEEP:
  107. i[0] = va_arg(list, int);
  108. fmtprint(&fmt, "%d", i[0]);
  109. break;
  110. case DUP:
  111. i[0] = va_arg(list, int);
  112. i[1] = va_arg(list, int);
  113. fmtprint(&fmt, "%d %d", i[0], i[1]);
  114. break;
  115. case ALARM:
  116. l = va_arg(list, unsigned long);
  117. fmtprint(&fmt, "%#lu ", l);
  118. break;
  119. case EXECAC:
  120. i[0] = va_arg(list, int);
  121. fmtprint(&fmt, "%d", i[0]);
  122. a = va_arg(list, char*);
  123. fmtuserstring(&fmt, a, " ");
  124. argv = va_arg(list, char**);
  125. evenaddr(PTR2UINT(argv));
  126. for(;;){
  127. a = *(char**)validaddr(argv, sizeof(char**), 0);
  128. if(a == nil)
  129. break;
  130. fmtprint(&fmt, " ");
  131. fmtuserstring(&fmt, a, "");
  132. argv++;
  133. }
  134. break;
  135. case EXEC:
  136. a = va_arg(list, char*);
  137. fmtuserstring(&fmt, a, "");
  138. argv = va_arg(list, char**);
  139. evenaddr(PTR2UINT(argv));
  140. for(;;){
  141. if (! okaddr((uintptr_t)argv, sizeof(char**), 0))
  142. break;
  143. a = *(char**)validaddr(argv, sizeof(char**), 0);
  144. if(a == nil)
  145. break;
  146. fmtprint(&fmt, " ");
  147. fmtuserstring(&fmt, a, "");
  148. argv++;
  149. }
  150. break;
  151. case _FSESSION: /* deprecated */
  152. case _FSTAT: /* deprecated */
  153. case _FWSTAT: /* obsolete */
  154. i[0] = va_arg(list, int);
  155. a = va_arg(list, char*);
  156. fmtprint(&fmt, "%d %#p", i[0], a);
  157. break;
  158. case FAUTH:
  159. i[0] = va_arg(list, int);
  160. a = va_arg(list, char*);
  161. fmtprint(&fmt, "%d", i[0]);
  162. fmtuserstring(&fmt, a, "");
  163. break;
  164. case SEGBRK:
  165. case RENDEZVOUS:
  166. v = va_arg(list, void*);
  167. fmtprint(&fmt, "%#p ", v);
  168. v = va_arg(list, void*);
  169. fmtprint(&fmt, "%#p", v);
  170. break;
  171. case _MOUNT: /* deprecated */
  172. i[0] = va_arg(list, int);
  173. fmtprint(&fmt, "%d ", i[0]);
  174. a = va_arg(list, char*);
  175. fmtuserstring(&fmt, a, " ");
  176. i[0] = va_arg(list, int);
  177. fmtprint(&fmt, "%#ux ", i[0]);
  178. a = va_arg(list, char*);
  179. fmtuserstring(&fmt, a, "");
  180. break;
  181. case OPEN:
  182. a = va_arg(list, char*);
  183. fmtuserstring(&fmt, a, " ");
  184. i[0] = va_arg(list, int);
  185. fmtprint(&fmt, "%#x", i[0]);
  186. break;
  187. case OSEEK: /* deprecated */
  188. i[0] = va_arg(list, int);
  189. l = va_arg(list, int32_t);
  190. i[1] = va_arg(list, int);
  191. fmtprint(&fmt, "%d %ld %d", i[0], l, i[1]);
  192. break;
  193. case SLEEP:
  194. l = va_arg(list, int32_t);
  195. fmtprint(&fmt, "%ld", l);
  196. break;
  197. case _STAT: /* obsolete */
  198. case _WSTAT: /* obsolete */
  199. a = va_arg(list, char*);
  200. fmtuserstring(&fmt, a, " ");
  201. a = va_arg(list, char*);
  202. fmtprint(&fmt, "%#p", a);
  203. break;
  204. case RFORK:
  205. i[0] = va_arg(list, int);
  206. fmtprint(&fmt, "%#x", i[0]);
  207. break;
  208. case PIPE:
  209. case BRK_:
  210. v = va_arg(list, int*);
  211. fmtprint(&fmt, "%#p", v);
  212. break;
  213. case CREATE:
  214. a = va_arg(list, char*);
  215. fmtuserstring(&fmt, a, " ");
  216. i[0] = va_arg(list, int);
  217. i[1] = va_arg(list, int);
  218. fmtprint(&fmt, "%#x %#x", i[0], i[1]);
  219. break;
  220. case FD2PATH:
  221. case FSTAT:
  222. case FWSTAT:
  223. i[0] = va_arg(list, int);
  224. a = va_arg(list, char*);
  225. l = va_arg(list, unsigned long);
  226. fmtprint(&fmt, "%d %#p %lu", i[0], a, l);
  227. break;
  228. case NOTIFY:
  229. case SEGDETACH:
  230. case _WAIT: /* deprecated */
  231. v = va_arg(list, void*);
  232. fmtprint(&fmt, "%#p", v);
  233. break;
  234. case SEGATTACH:
  235. i[0] = va_arg(list, int);
  236. fmtprint(&fmt, "%d ", i[0]);
  237. a = va_arg(list, char*);
  238. fmtuserstring(&fmt, a, " ");
  239. /*FALLTHROUGH*/
  240. case SEGFREE:
  241. case SEGFLUSH:
  242. v = va_arg(list, void*);
  243. l = va_arg(list, unsigned long);
  244. fmtprint(&fmt, "%#p %lu", v, l);
  245. break;
  246. case UNMOUNT:
  247. a = va_arg(list, char*);
  248. fmtuserstring(&fmt, a, " ");
  249. a = va_arg(list, char*);
  250. fmtuserstring(&fmt, a, "");
  251. break;
  252. case SEMACQUIRE:
  253. case SEMRELEASE:
  254. v = va_arg(list, int*);
  255. i[0] = va_arg(list, int);
  256. fmtprint(&fmt, "%#p %d", v, i[0]);
  257. break;
  258. case TSEMACQUIRE:
  259. v = va_arg(list, int*);
  260. l = va_arg(list, uint32_t);
  261. fmtprint(&fmt, "%#p %ld", v, l);
  262. break;
  263. case SEMSLEEP:
  264. case SEMWAKEUP:
  265. v = va_arg(list, int*);
  266. fmtprint(&fmt, "%#p", v);
  267. break;
  268. case SEMALT:
  269. ip = va_arg(list, int**);
  270. i[0] = va_arg(list, int);
  271. validaddr(ip, sizeof(int*)*i[0], 0);
  272. fmtprint(&fmt, "%#p %d", ip, i[0]);
  273. break;
  274. case SEEK:
  275. v = va_arg(list, int64_t*);
  276. i[0] = va_arg(list, int);
  277. vl = va_arg(list, int64_t);
  278. i[1] = va_arg(list, int);
  279. fmtprint(&fmt, "%d %#llx %d", i[0], vl, i[1]);
  280. break;
  281. case FVERSION:
  282. i[0] = va_arg(list, int);
  283. i[1] = va_arg(list, int);
  284. fmtprint(&fmt, "%d %d ", i[0], i[1]);
  285. a = va_arg(list, char*);
  286. fmtuserstring(&fmt, a, " ");
  287. l = va_arg(list, unsigned long);
  288. fmtprint(&fmt, "%lu", l);
  289. break;
  290. case WSTAT:
  291. case STAT:
  292. a = va_arg(list, char*);
  293. fmtuserstring(&fmt, a, " ");
  294. v = va_arg(list, void*);
  295. l = va_arg(list, unsigned long);
  296. fmtprint(&fmt, "%#p %lu", v, l);
  297. break;
  298. case ERRSTR:
  299. a = va_arg(list, char*);
  300. l = va_arg(list, unsigned long);
  301. fmtuserstring(&fmt, a, " ");
  302. fmtprint(&fmt, "%lu", l);
  303. break;
  304. case AWAIT:
  305. a = va_arg(list, char*);
  306. l = va_arg(list, unsigned long);
  307. fmtprint(&fmt, "%#p %lu", a, l);
  308. break;
  309. case MOUNT:
  310. i[0] = va_arg(list, int);
  311. i[1] = va_arg(list, int);
  312. fmtprint(&fmt, "%d %d ", i[0], i[1]);
  313. a = va_arg(list, char*);
  314. fmtuserstring(&fmt, a, " ");
  315. i[0] = va_arg(list, int);
  316. fmtprint(&fmt, "%#x ", i[0]);
  317. a = va_arg(list, char*);
  318. fmtuserstring(&fmt, a, "");
  319. break;
  320. case READ: /* deprecated */
  321. case PREAD:
  322. i[0] = va_arg(list, int);
  323. fmtprint(&fmt, "%d ", i[0]);
  324. v = va_arg(list, void*);
  325. l = va_arg(list, int32_t);
  326. vl = va_arg(list, int64_t);
  327. if (what == 'E') {
  328. fmtprint(&fmt, "%#P %ld 0x%llx", v, l, vl);
  329. }
  330. break;
  331. case WRITE: /* deprecated */
  332. case PWRITE:
  333. i[0] = va_arg(list, int);
  334. v = va_arg(list, void*);
  335. l = va_arg(list, int32_t);
  336. fmtprint(&fmt, "%d ", i[0]);
  337. len = MIN(l, 64);
  338. fmtrwdata(&fmt, v, len, " ");
  339. fmtprint(&fmt, "%ld 0x%llx", l, vl);
  340. break;
  341. }
  342. if (what == 'E') {
  343. fmtprint(&fmt, "\n");
  344. up->syscalltrace = fmtstrflush(&fmt);
  345. return;
  346. }
  347. errstr = "\"\"";
  348. switch(syscallno){
  349. default:
  350. if(ar0->i == -1)
  351. errstr = up->syserrstr;
  352. fmtprint(&fmt, " = %d", ar0->i);
  353. break;
  354. case SEEK:
  355. if(ar0->vl == -1)
  356. errstr = up->syserrstr;
  357. fmtprint(&fmt, " = %lld", ar0->vl);
  358. break;
  359. case NSEC:
  360. fmtprint(&fmt, " = %lld", ar0->vl);
  361. break;
  362. case ALARM:
  363. case WRITE:
  364. case PWRITE:
  365. if(ar0->l == -1)
  366. errstr = up->syserrstr;
  367. fmtprint(&fmt, " = %ld", ar0->l);
  368. break;
  369. case EXEC:
  370. case EXECAC:
  371. case SEGBRK:
  372. case SEGATTACH:
  373. case RENDEZVOUS:
  374. if(ar0->v == (void*)-1)
  375. errstr = up->syserrstr;
  376. fmtprint(&fmt, " = %#p", ar0->v);
  377. break;
  378. case RFORK:
  379. if(ar0->v == (void*)-1)
  380. errstr = up->syserrstr;
  381. fmtprint(&fmt, " = %d", ar0->v);
  382. break;
  383. case AWAIT:
  384. if(ar0->i > 0){
  385. fmtuserstring(&fmt, a, " ");
  386. fmtprint(&fmt, "%lu = %d", l, ar0->i);
  387. }
  388. else{
  389. fmtprint(&fmt, "%#p/\"\" %lu = %d", a, l, ar0->i);
  390. errstr = up->syserrstr;
  391. }
  392. break;
  393. case _ERRSTR:
  394. case ERRSTR:
  395. fmtuserstring(&fmt, a, " ");
  396. fmtprint(&fmt, "%lu = %d", l, ar0->i);
  397. break;
  398. case FD2PATH:
  399. if(ar0->i > 0){
  400. fmtuserstring(&fmt, a, " ");
  401. fmtprint(&fmt, "%lu = %d", l, ar0->i);
  402. }
  403. else{
  404. fmtprint(&fmt, "\"\" %lu = %d", l, ar0->i);
  405. errstr = up->syserrstr;
  406. }
  407. break;
  408. case READ:
  409. case PREAD:
  410. if(ar0->l >= 0){
  411. len = MIN(ar0->l, 64);
  412. fmtrwdata(&fmt, v, len, "");
  413. }
  414. else{
  415. fmtprint(&fmt, " %#p/\"\"", v);
  416. errstr = up->syserrstr;
  417. }
  418. fmtprint(&fmt, " %ld 0x%llx = %d", l, vl, ar0->i);
  419. break;
  420. }
  421. fmtprint(&fmt, " %s %#llu %#llu\n", errstr, start, stop);
  422. up->syscalltrace = fmtstrflush(&fmt);
  423. }