main.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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. * db - main command loop and error/interrupt handling
  11. */
  12. #include "defs.h"
  13. #include "fns.h"
  14. int wtflag = OREAD;
  15. BOOL kflag;
  16. BOOL mkfault;
  17. ADDR maxoff;
  18. int xargc; /* bullshit */
  19. extern BOOL executing;
  20. extern int infile;
  21. int exitflg;
  22. extern int eof;
  23. int alldigs(char*);
  24. void fault(void*, char*);
  25. extern char *Ipath;
  26. jmp_buf env;
  27. static char *errmsg;
  28. void
  29. main(int argc, char **argv)
  30. {
  31. char b1[100];
  32. char b2[100];
  33. char *s;
  34. char *name;
  35. name = 0;
  36. outputinit();
  37. maxoff = MAXOFF;
  38. ARGBEGIN{
  39. case 'k':
  40. kflag = 1;
  41. break;
  42. case 'w':
  43. wtflag = ORDWR; /* suitable for open() */
  44. break;
  45. case 'I':
  46. s = ARGF();
  47. if(s == 0)
  48. dprint("missing -I argument\n");
  49. else
  50. Ipath = s;
  51. break;
  52. case 'm':
  53. name = ARGF();
  54. if(name == 0)
  55. dprint("missing -m argument\n");
  56. break;
  57. }ARGEND
  58. symfil = 0;
  59. corfil = 0;
  60. if (argc > 0 && !alldigs(argv[0])) {
  61. symfil = argv[0];
  62. argv++;
  63. argc--;
  64. }
  65. if(argc==1 && alldigs(argv[0])){
  66. char *cpu, *p, *q;
  67. pid = atoi(argv[0]);
  68. pcsactive = 0;
  69. if (!symfil) {
  70. if(kflag){
  71. cpu = getenv("cputype");
  72. if(cpu == 0){
  73. cpu = "386";
  74. dprint("$cputype not set; assuming %s\n", cpu);
  75. }
  76. p = getenv("terminal");
  77. if(p==0 || (p=strchr(p, ' '))==0 || p[1]==' ' || p[1]==0){
  78. strcpy(b1, "/386/9pc");
  79. dprint("missing or bad $terminal; assuming %s\n", b1);
  80. }else{
  81. p++;
  82. q = strchr(p, ' ');
  83. if(q)
  84. *q = 0;
  85. sprint(b1, "/%s/9%s", cpu, p);
  86. }
  87. }else
  88. sprint(b1, "/proc/%s/text", argv[0]);
  89. symfil = b1;
  90. }
  91. sprint(b2, "/proc/%s/mem", argv[0]);
  92. corfil = b2;
  93. } else if (argc > 0) {
  94. fprint(2, "Usage: db [-kw] [-m machine] [-I dir] [symfile] [pid]\n");
  95. exits("usage");
  96. }
  97. if (!symfil)
  98. symfil = "8.out";
  99. xargc = argc;
  100. notify(fault);
  101. setsym();
  102. dotmap = dumbmap(-1);
  103. if (name && machbyname(name) == 0)
  104. dprint("unknown machine %s\n", name);
  105. dprint("%s binary\n", mach->name);
  106. if(setjmp(env) == 0){
  107. if (corfil) {
  108. setcor(); /* could get error */
  109. dprint("%s\n", machdata->excep(cormap, rget));
  110. printpc();
  111. }
  112. }
  113. setjmp(env);
  114. if (executing)
  115. delbp();
  116. executing = FALSE;
  117. for (;;) {
  118. flushbuf();
  119. if (errmsg) {
  120. dprint(errmsg);
  121. printc('\n');
  122. errmsg = 0;
  123. exitflg = 0;
  124. }
  125. if (mkfault) {
  126. mkfault=0;
  127. printc('\n');
  128. prints(DBNAME);
  129. }
  130. clrinp();
  131. rdc();
  132. reread();
  133. if (eof) {
  134. if (infile == STDIN)
  135. done();
  136. iclose(-1, 0);
  137. eof = 0;
  138. longjmp(env, 1);
  139. }
  140. exitflg = 0;
  141. command(0, 0);
  142. reread();
  143. if (rdc() != '\n')
  144. error("newline expected");
  145. }
  146. }
  147. int
  148. alldigs(char *s)
  149. {
  150. while(*s){
  151. if(*s<'0' || '9'<*s)
  152. return 0;
  153. s++;
  154. }
  155. return 1;
  156. }
  157. void
  158. done(void)
  159. {
  160. if (pid)
  161. endpcs();
  162. exits(exitflg? "error": 0);
  163. }
  164. /*
  165. * An error occurred; save the message for later printing,
  166. * close open files, and reset to main command loop.
  167. */
  168. void
  169. error(char *n)
  170. {
  171. errmsg = n;
  172. iclose(0, 1);
  173. oclose();
  174. flush();
  175. delbp();
  176. ending = 0;
  177. longjmp(env, 1);
  178. }
  179. void
  180. errors(char *m, char *n)
  181. {
  182. static char buf[128];
  183. sprint(buf, "%s: %s", m, n);
  184. error(buf);
  185. }
  186. /*
  187. * An interrupt occurred;
  188. * seek to the end of the current file
  189. * and remember that there was a fault.
  190. */
  191. void
  192. fault(void *a, char *s)
  193. {
  194. USED(a);
  195. if(strncmp(s, "interrupt", 9) == 0){
  196. seek(infile, 0L, 2);
  197. mkfault++;
  198. noted(NCONT);
  199. }
  200. noted(NDFLT);
  201. }