trcrun.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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. /*
  10. * functions for running the debugged process
  11. */
  12. #include "defs.h"
  13. #include "fns.h"
  14. int child;
  15. int msgfd = -1;
  16. int notefd = -1;
  17. int pcspid = -1;
  18. int pcsactive = 0;
  19. void
  20. setpcs(void)
  21. {
  22. char buf[128];
  23. if(pid && pid != pcspid){
  24. if(msgfd >= 0){
  25. close(msgfd);
  26. msgfd = -1;
  27. }
  28. if(notefd >= 0){
  29. close(notefd);
  30. notefd = -1;
  31. }
  32. pcspid = -1;
  33. sprint(buf, "/proc/%d/ctl", pid);
  34. msgfd = open(buf, OWRITE);
  35. if(msgfd < 0)
  36. error("can't open control file");
  37. sprint(buf, "/proc/%d/note", pid);
  38. notefd = open(buf, ORDWR);
  39. if(notefd < 0)
  40. error("can't open note file");
  41. pcspid = pid;
  42. }
  43. }
  44. void
  45. msgpcs(char *msg)
  46. {
  47. char err[ERRMAX];
  48. setpcs();
  49. if(write(msgfd, msg, strlen(msg)) < 0 && !ending){
  50. errstr(err, sizeof err);
  51. if(strcmp(err, "interrupted") != 0)
  52. endpcs();
  53. errors("can't write control file", err);
  54. }
  55. }
  56. /*
  57. * empty the note buffer and toss pending breakpoint notes
  58. */
  59. void
  60. unloadnote(void)
  61. {
  62. char err[ERRMAX];
  63. setpcs();
  64. for(; nnote<NNOTE; nnote++){
  65. switch(read(notefd, note[nnote], sizeof note[nnote])){
  66. case -1:
  67. errstr(err, sizeof err);
  68. if(strcmp(err, "interrupted") != 0)
  69. endpcs();
  70. errors("can't read note file", err);
  71. case 0:
  72. return;
  73. }
  74. note[nnote][ERRMAX-1] = '\0';
  75. if(strncmp(note[nnote], "sys: breakpoint", 15) == 0)
  76. --nnote;
  77. }
  78. }
  79. /*
  80. * reload the note buffer
  81. */
  82. void
  83. loadnote(void)
  84. {
  85. int i;
  86. char err[ERRMAX];
  87. setpcs();
  88. for(i=0; i<nnote; i++){
  89. if(write(notefd, note[i], strlen(note[i])) < 0){
  90. errstr(err, sizeof err);
  91. if(strcmp(err, "interrupted") != 0)
  92. endpcs();
  93. errors("can't write note file", err);
  94. }
  95. }
  96. nnote = 0;
  97. }
  98. void
  99. notes(void)
  100. {
  101. int n;
  102. if(nnote == 0)
  103. return;
  104. dprint("notes:\n");
  105. for(n=0; n<nnote; n++)
  106. dprint("%d:\t%s\n", n, note[n]);
  107. }
  108. void
  109. killpcs(void)
  110. {
  111. msgpcs("kill");
  112. }
  113. void
  114. grab(void)
  115. {
  116. flush();
  117. msgpcs("stop");
  118. bpwait();
  119. }
  120. void
  121. ungrab(void)
  122. {
  123. msgpcs("start");
  124. }
  125. void
  126. doexec(void)
  127. {
  128. char *argl[MAXARG];
  129. char args[LINSIZ];
  130. char *p;
  131. char **ap;
  132. char *thisarg;
  133. ap = argl;
  134. p = args;
  135. *ap++ = symfil;
  136. for (rdc(); lastc != EOR;) {
  137. thisarg = p;
  138. if (lastc == '<' || lastc == '>') {
  139. *p++ = lastc;
  140. rdc();
  141. }
  142. while (lastc != EOR && lastc != SPC && lastc != TB) {
  143. *p++ = lastc;
  144. readchar();
  145. }
  146. if (lastc == SPC || lastc == TB)
  147. rdc();
  148. *p++ = 0;
  149. if (*thisarg == '<') {
  150. close(0);
  151. if (open(&thisarg[1], OREAD) < 0) {
  152. print("%s: cannot open\n", &thisarg[1]);
  153. _exits(0);
  154. }
  155. }
  156. else if (*thisarg == '>') {
  157. close(1);
  158. if (create(&thisarg[1], OWRITE, 0666) < 0) {
  159. print("%s: cannot create\n", &thisarg[1]);
  160. _exits(0);
  161. }
  162. }
  163. else
  164. *ap++ = thisarg;
  165. }
  166. *ap = 0;
  167. exec(symfil, argl);
  168. perror(symfil);
  169. }
  170. char procname[100];
  171. void
  172. startpcs(void)
  173. {
  174. if ((pid = fork()) == 0) {
  175. pid = getpid();
  176. msgpcs("hang");
  177. doexec();
  178. exits(0);
  179. }
  180. if (pid == -1)
  181. error("can't fork");
  182. child++;
  183. sprint(procname, "/proc/%d/mem", pid);
  184. corfil = procname;
  185. msgpcs("waitstop");
  186. bpwait();
  187. if (adrflg)
  188. rput(cormap, mach->pc, adrval);
  189. while (rdc() != EOR)
  190. ;
  191. reread();
  192. }
  193. void
  194. runstep(uint64_t loc, int keepnote)
  195. {
  196. int nfoll;
  197. uint64_t foll[3];
  198. BKPT bkpt[3];
  199. int i;
  200. if(machdata->foll == 0){
  201. dprint("stepping unimplemented; assuming not a branch\n");
  202. nfoll = 1;
  203. foll[0] = loc+mach->pcquant;
  204. }else {
  205. nfoll = machdata->foll(cormap, loc, rget, foll);
  206. if (nfoll < 0)
  207. error("%r");
  208. }
  209. memset(bkpt, 0, sizeof bkpt);
  210. for(i=0; i<nfoll; i++){
  211. if(foll[i] == loc)
  212. error("can't single step: next instruction is dot");
  213. bkpt[i].loc = foll[i];
  214. bkput(&bkpt[i], 1);
  215. }
  216. runrun(keepnote);
  217. for(i=0; i<nfoll; i++)
  218. bkput(&bkpt[i], 0);
  219. }
  220. void
  221. bpwait(void)
  222. {
  223. setcor();
  224. unloadnote();
  225. }
  226. void
  227. runrun(int keepnote)
  228. {
  229. int on;
  230. on = nnote;
  231. unloadnote();
  232. if(on != nnote){
  233. notes();
  234. error("not running: new notes pending");
  235. }
  236. if(keepnote)
  237. loadnote();
  238. else
  239. nnote = 0;
  240. flush();
  241. msgpcs("startstop");
  242. bpwait();
  243. }
  244. void
  245. bkput(BKPT *bp, int install)
  246. {
  247. char buf[256];
  248. ADDR loc;
  249. int ret;
  250. errstr(buf, sizeof buf);
  251. if(machdata->bpfix)
  252. loc = (*machdata->bpfix)(bp->loc);
  253. else
  254. loc = bp->loc;
  255. if(install){
  256. ret = get1(cormap, loc, bp->save, machdata->bpsize);
  257. if (ret > 0)
  258. ret = put1(cormap, loc, machdata->bpinst, machdata->bpsize);
  259. }else
  260. ret = put1(cormap, loc, bp->save, machdata->bpsize);
  261. if(ret < 0){
  262. sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc);
  263. print(buf);
  264. read(0, buf, 100);
  265. }
  266. }