run.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. /* $Header$ */
  2. /* Running a process and communication */
  3. #include <signal.h>
  4. #include <stdio.h>
  5. #include <assert.h>
  6. #include <alloc.h>
  7. #include "ops.h"
  8. #include "message.h"
  9. #include "position.h"
  10. #include "tree.h"
  11. #include "file.h"
  12. #include "symbol.h"
  13. #include "idf.h"
  14. #include "scope.h"
  15. #define MAXARG 128
  16. extern char *strncpy();
  17. extern char *AObj;
  18. extern t_lineno currline;
  19. extern FILE *db_out;
  20. extern int debug;
  21. extern struct idf *str2idf();
  22. extern long pointer_size;
  23. static int child_pid; /* process id of child */
  24. static int to_child, from_child; /* file descriptors for communication */
  25. static int child_status;
  26. static int restoring;
  27. int db_ss;
  28. static int catch_sigpipe();
  29. static int stopped();
  30. static int uputm(), ugetm();
  31. static int fild1[2], fild2[2]; /* pipe file descriptors */
  32. int
  33. init_run()
  34. {
  35. /* take file descriptors so that listing cannot take them */
  36. int i;
  37. for (i = IN_FD; i <= OUT_FD; i++) close(i);
  38. if (pipe(fild1) < 0 ||
  39. pipe(fild2) < 0 ||
  40. fild1[0] != IN_FD ||
  41. fild2[1] != OUT_FD) {
  42. return 0;
  43. }
  44. to_child = fild1[1];
  45. from_child = fild2[0];
  46. return 1;
  47. }
  48. int
  49. start_child(p)
  50. p_tree p;
  51. {
  52. /* start up the process to be debugged and set up communication */
  53. char *argp[MAXARG]; /* argument list */
  54. register p_tree pt = p->t_args[0], pt1;
  55. unsigned int nargs = 1; /* #args */
  56. char *in_redirect = 0; /* standard input redirected */
  57. char *out_redirect = 0; /* standard output redirected */
  58. signal_child(SIGKILL); /* like families in China, this debugger is only
  59. allowed one child
  60. */
  61. /* first check arguments and redirections and build argument list */
  62. while (pt) {
  63. switch(pt->t_oper) {
  64. case OP_LINK:
  65. pt1 = pt->t_args[1];
  66. pt = pt->t_args[0];
  67. continue;
  68. case OP_NAME:
  69. if (nargs < (MAXARG-1)) {
  70. argp[nargs++] = pt->t_str;
  71. }
  72. else {
  73. error("too many arguments");
  74. return 0;
  75. }
  76. break;
  77. case OP_INPUT:
  78. if (in_redirect) {
  79. error("input redirected twice?");
  80. return 0;
  81. }
  82. in_redirect = pt->t_str;
  83. break;
  84. case OP_OUTPUT:
  85. if (out_redirect) {
  86. error("output redirected twice?");
  87. return 0;
  88. }
  89. out_redirect = pt->t_str;
  90. break;
  91. }
  92. if (pt != pt1) pt = pt1;
  93. else break;
  94. }
  95. argp[0] = AObj;
  96. argp[nargs] = 0;
  97. /* create child process */
  98. child_pid = fork();
  99. if (child_pid < 0) {
  100. error("could not create child");
  101. return 0;
  102. }
  103. if (child_pid == 0) {
  104. /* this is the child process */
  105. close(fild1[1]);
  106. close(fild2[0]);
  107. signal(SIGINT, SIG_IGN);
  108. /* I/O redirection */
  109. if (in_redirect) {
  110. int fd;
  111. close(0);
  112. if ((fd = open(in_redirect, 0)) < 0) {
  113. error("could not open input file");
  114. exit(-1);
  115. }
  116. if (fd != 0) {
  117. dup2(fd, 0);
  118. close(fd);
  119. }
  120. }
  121. if (out_redirect) {
  122. int fd;
  123. close(1);
  124. if ((fd = creat(in_redirect, 0666)) < 0) {
  125. error("could not open output file");
  126. exit(-1);
  127. }
  128. if (fd != 1) {
  129. dup2(fd, 1);
  130. close(fd);
  131. }
  132. }
  133. /* and run process to be debugged */
  134. execv(AObj, argp);
  135. error("could not exec %s", AObj);
  136. exit(-1);
  137. }
  138. /* debugger */
  139. close(fild1[0]);
  140. close(fild2[1]);
  141. pipe(fild1); /* to occupy file descriptors */
  142. signal(SIGPIPE, catch_sigpipe);
  143. if (! wait_for_child((char *) 0)) {
  144. error("child not responding");
  145. return 0;
  146. }
  147. do_items();
  148. if (! restoring) send_cont(1);
  149. return 1;
  150. }
  151. int
  152. wait_for_child(s)
  153. char *s; /* to pass on to 'stopped' */
  154. {
  155. struct message_hdr m;
  156. if (child_pid) {
  157. if (ugetm(&m)) {
  158. return stopped(s, (t_addr) m.m_size);
  159. }
  160. return 0;
  161. }
  162. return 1;
  163. }
  164. signal_child(sig)
  165. {
  166. if (child_pid) {
  167. kill(child_pid, sig);
  168. if (sig == SIGKILL) {
  169. wait(&child_status);
  170. init_run();
  171. }
  172. }
  173. }
  174. static int
  175. catch_sigpipe()
  176. {
  177. child_pid = 0;
  178. }
  179. static int
  180. ureceive(p, c)
  181. char *p;
  182. long c;
  183. {
  184. int i;
  185. if (! child_pid) return 0;
  186. while (c >= 0x1000) {
  187. i = read(from_child, p, 0x1000);
  188. if (i <= 0) {
  189. if (i == 0) child_pid = 0;
  190. return 0;
  191. }
  192. p += i;
  193. c -= i;
  194. }
  195. while (c > 0) {
  196. i = read(from_child, p, (int)c);
  197. if (i <= 0) {
  198. if (i == 0) child_pid = 0;
  199. return 0;
  200. }
  201. p += i;
  202. c -= i;
  203. }
  204. return c == 0;
  205. }
  206. static int
  207. usend(p, c)
  208. char *p;
  209. long c;
  210. {
  211. int i;
  212. while (c >= 0x1000) {
  213. i = write(to_child, p, 0x1000);
  214. if (i < 0) return 0;
  215. p += i;
  216. c -= i;
  217. }
  218. while (c > 0) {
  219. i = write(to_child, p, (int)c);
  220. if (i < 0) return 0;
  221. p += i;
  222. c -= i;
  223. }
  224. return 1;
  225. }
  226. static int
  227. ugetm(message)
  228. struct message_hdr *message;
  229. {
  230. if (! ureceive((char *) message, (long) sizeof(struct message_hdr))) {
  231. return 0;
  232. }
  233. if (debug) printf("Got %d\n", message->m_type);
  234. return 1;
  235. }
  236. static int
  237. uputm(message)
  238. struct message_hdr *message;
  239. {
  240. if (! usend((char *) message, (long) sizeof(struct message_hdr))) {
  241. return 0;
  242. }
  243. if (debug) printf("Sent %d\n", message->m_type);
  244. return 1;
  245. }
  246. static struct message_hdr answer;
  247. static int single_stepping;
  248. static int
  249. stopped(s, a)
  250. char *s; /* stop message */
  251. t_addr a; /* address where stopped */
  252. {
  253. p_position pos;
  254. if (s) {
  255. fprintf(db_out, "%s ", s);
  256. pos = print_position((t_addr) a, 1);
  257. newfile(str2idf(pos->filename, 1));
  258. currline = pos->lineno;
  259. fputs("\n", db_out);
  260. lines(currfile->sy_file, (int)currline, (int)currline);
  261. }
  262. return 1;
  263. }
  264. static int
  265. could_send(m, stop_message)
  266. struct message_hdr *m;
  267. {
  268. int type;
  269. t_addr a;
  270. for (;;) {
  271. if (child_pid) {
  272. if (! uputm(m) ||
  273. ! ugetm(&answer)) {
  274. if (child_pid) {
  275. error("something wrong!");
  276. return 1;
  277. }
  278. wait(&child_status);
  279. init_run();
  280. if (child_status & 0177) {
  281. fprintf(db_out,
  282. "Child died with signal %d\n",
  283. child_status & 0177);
  284. }
  285. else {
  286. fprintf(db_out,
  287. "Child terminated, exit status %d\n",
  288. child_status >> 8);
  289. }
  290. return 1;
  291. }
  292. a = answer.m_size;
  293. type = answer.m_type;
  294. if (m->m_type & DB_RUN) {
  295. /* run command */
  296. CurrentScope = get_scope_from_addr((t_addr) a);
  297. if (! item_addr_actions(a) &&
  298. ( type == DB_SS || type == OK)) {
  299. /* no explicit breakpoints at this position.
  300. Also, child did not stop because of
  301. SETSS or SETSSF, otherwise we would
  302. have gotten END_SS.
  303. So, continue.
  304. */
  305. if ((m->m_type & ~ DB_SS) != CONT) {
  306. m->m_type = CONT | (m->m_type & DB_SS);
  307. }
  308. continue;
  309. }
  310. if (type != END_SS && single_stepping) {
  311. m->m_type = CLRSS;
  312. uputm(m) && ugetm(&answer);
  313. }
  314. single_stepping = 0;
  315. }
  316. if (stop_message) stopped("stopped", a);
  317. return 1;
  318. }
  319. return 0;
  320. }
  321. /*NOTREACHED*/
  322. }
  323. int
  324. get_bytes(size, from, to)
  325. long size;
  326. t_addr from;
  327. char *to;
  328. {
  329. struct message_hdr m;
  330. m.m_type = GETBYTES;
  331. m.m_size = size;
  332. ATOBUF(m.m_buf, (char *) from);
  333. if (! could_send(&m, 0)) {
  334. return 0;
  335. }
  336. assert(answer.m_type == DATA && answer.m_size == m.m_size);
  337. return ureceive(to, answer.m_size);
  338. }
  339. int
  340. get_dump(globmessage, globbuf, stackmessage, stackbuf)
  341. struct message_hdr *globmessage, *stackmessage;
  342. char **globbuf, **stackbuf;
  343. {
  344. struct message_hdr m;
  345. m.m_type = DUMP;
  346. if (! could_send(&m, 0)) {
  347. return 0;
  348. }
  349. assert(answer.m_type == DGLOB);
  350. *globmessage = answer;
  351. *globbuf = Malloc((unsigned) answer.m_size);
  352. if (! ureceive(*globbuf, answer.m_size) || ! ugetm(stackmessage)) {
  353. free(*globbuf);
  354. return 0;
  355. }
  356. assert(stackmessage->m_type == DSTACK);
  357. *stackbuf = Malloc((unsigned) stackmessage->m_size);
  358. if (! ureceive(*stackbuf, stackmessage->m_size)) {
  359. free(*globbuf);
  360. free(*stackbuf);
  361. return 0;
  362. }
  363. ATOBUF(globmessage->m_buf+SP_OFF*pointer_size,
  364. BUFTOA(stackmessage->m_buf+SP_OFF*pointer_size));
  365. return 1;
  366. }
  367. int
  368. put_dump(globmessage, globbuf, stackmessage, stackbuf)
  369. struct message_hdr *globmessage, *stackmessage;
  370. char *globbuf, *stackbuf;
  371. {
  372. struct message_hdr m;
  373. if (! child_pid) {
  374. restoring = 1;
  375. start_child(run_command);
  376. restoring = 0;
  377. }
  378. return uputm(globmessage) &&
  379. usend(globbuf, globmessage->m_size) &&
  380. uputm(stackmessage) &&
  381. usend(stackbuf, stackmessage->m_size) &&
  382. ugetm(&m) && stopped("restored", m.m_size);
  383. }
  384. t_addr *
  385. get_EM_regs(level)
  386. int level;
  387. {
  388. struct message_hdr m;
  389. static t_addr buf[5];
  390. register t_addr *to = &buf[0];
  391. m.m_type = GETEMREGS;
  392. m.m_size = level;
  393. if (! could_send(&m, 0)) {
  394. return 0;
  395. }
  396. *to++ = (t_addr) BUFTOA(answer.m_buf);
  397. *to++ = (t_addr) BUFTOA(answer.m_buf+pointer_size);
  398. *to++ = (t_addr) BUFTOA(answer.m_buf+2*pointer_size);
  399. *to++ = (t_addr) BUFTOA(answer.m_buf+3*pointer_size);
  400. *to++ = (t_addr) BUFTOA(answer.m_buf+4*pointer_size);
  401. return buf;
  402. }
  403. int
  404. set_pc(PC)
  405. t_addr PC;
  406. {
  407. struct message_hdr m;
  408. m.m_type = SETEMREGS;
  409. m.m_size = 0;
  410. ATOBUF(m.m_buf+PC_OFF*pointer_size, (char *)PC);
  411. return could_send(&m, 0);
  412. }
  413. int
  414. send_cont(stop_message)
  415. int stop_message;
  416. {
  417. struct message_hdr m;
  418. m.m_type = (CONT | (db_ss ? DB_SS : 0));
  419. m.m_size = 0;
  420. return could_send(&m, stop_message);
  421. }
  422. int
  423. do_single_step(type, count)
  424. int type;
  425. long count;
  426. {
  427. struct message_hdr m;
  428. m.m_type = type | (db_ss ? DB_SS : 0);
  429. m.m_size = count;
  430. single_stepping = 1;
  431. if (could_send(&m, 1)) {
  432. return 1;
  433. }
  434. single_stepping = 0;
  435. return 0;
  436. }
  437. int
  438. set_or_clear_breakpoint(a, type)
  439. t_addr a;
  440. int type;
  441. {
  442. struct message_hdr m;
  443. if (a == ILL_ADDR || a == NO_ADDR) return 0;
  444. m.m_type = type;
  445. m.m_size = a;
  446. if (debug) printf("%s breakpoint at 0x%lx\n", type == SETBP ? "setting" : "clearing", (long) a);
  447. if (! could_send(&m, 0)) { }
  448. return 1;
  449. }
  450. int
  451. set_or_clear_trace(start, end, type)
  452. t_addr start, end;
  453. int type;
  454. {
  455. struct message_hdr m;
  456. m.m_type = type;
  457. ATOBUF(m.m_buf, (char *) start);
  458. ATOBUF(m.m_buf+pointer_size, (char *) end);
  459. if (debug) printf("%s trace at [0x%lx,0x%lx]\n", type == SETTRACE ? "setting" : "clearing", (long) start, (long) end);
  460. if (! could_send(&m, 0)) { }
  461. return 1;
  462. }