1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)trinfo.c 1.2 02/11/82"; 4 5 /* 6 * Trace information management. 7 * 8 * The trace information is a list of variables that are being 9 * traced or whose value changing should cause a stop. 10 */ 11 12 #include "defs.h" 13 #include "breakpoint.h" 14 #include "process.h" 15 #include "machine.h" 16 #include "sym.h" 17 #include "tree.h" 18 #include "source.h" 19 #include "object.h" 20 #include "tree/tree.rep" 21 22 /* 23 * When tracing variables we keep a copy of their most recent value 24 * and compare it to the current one each time a breakpoint occurs. 25 * MAXTRSIZE is the maximum size variable we allow. 26 */ 27 28 #define MAXTRSIZE 512 29 30 /* 31 * The tracing structure is a list of information about all the 32 * variables that are being traced. 33 */ 34 35 typedef struct trinfo { 36 TRTYPE trtype; 37 ADDRESS traddr; 38 SYM *trblock; 39 NODE *trvar; 40 NODE *trcond; 41 char *trvalue; 42 struct trinfo *trnext; 43 } TRINFO; 44 45 LOCAL TRINFO *trhead; 46 47 /* 48 * add a variable to be traced 49 */ 50 51 addvar(trtype, node, cond) 52 TRTYPE trtype; 53 NODE *node; 54 NODE *cond; 55 { 56 register TRINFO *tp; 57 58 tp = alloc(1, TRINFO); 59 tp->trtype = trtype; 60 tp->traddr = (ADDRESS) -1; 61 tp->trblock = curfunc; 62 tp->trvar = node; 63 tp->trcond = cond; 64 tp->trvalue = NIL; 65 tp->trnext = trhead; 66 trhead = tp; 67 } 68 69 /* 70 * remove a variable from the trace list 71 */ 72 73 delvar(trtype, node, cond) 74 TRTYPE trtype; 75 NODE *node; 76 NODE *cond; 77 { 78 register TRINFO *tp, *last; 79 80 last = NIL; 81 for (tp = trhead; tp != NIL; tp = tp->trnext) { 82 if (tp->trtype == trtype && 83 tr_equal(tp->trvar, node) && 84 tr_equal(tp->trcond, cond)) { 85 break; 86 } 87 } 88 if (tp == NIL) { 89 trerror("can't delete term %t", node); 90 } 91 if (last == NIL) { 92 trhead = tp->trnext; 93 } else { 94 last->trnext = tp->trnext; 95 } 96 if (tp->trvalue != NIL) { 97 free(tp->trvalue); 98 } 99 free(tp); 100 } 101 102 /* 103 * Print out any news about variables in the list whose 104 * values have changed. 105 */ 106 107 prvarnews() 108 { 109 register TRINFO *tp; 110 register NODE *p; 111 register int n; 112 SYM *s; 113 char buff[MAXTRSIZE]; 114 static LINENO prevline; 115 116 for (tp = trhead; tp != NIL; tp = tp->trnext) { 117 if (tp->trcond != NIL && !cond(tp->trcond)) { 118 continue; 119 } 120 s = curfunc; 121 while (s != NIL && s != tp->trblock) { 122 s = container(s); 123 } 124 if (s == NIL) { 125 continue; 126 } 127 p = tp->trvar; 128 if (tp->traddr == (ADDRESS) -1) { 129 tp->traddr = lval(p->left); 130 } 131 n = size(p->nodetype); 132 dread(buff, tp->traddr, n); 133 if (tp->trvalue == NIL) { 134 tp->trvalue = alloc(n, char); 135 mov(buff, tp->trvalue, n); 136 mov(buff, sp, n); 137 sp += n; 138 if (tp->trtype == TRPRINT) { 139 printf("initially (at "); 140 printwhere(curline, srcfilename(pc)); 141 printf("):\t"); 142 prtree(p); 143 printf(" = "); 144 printval(p->nodetype); 145 putchar('\n'); 146 } 147 } else if (cmp(tp->trvalue, buff, n) != 0) { 148 mov(buff, tp->trvalue, n); 149 mov(buff, sp, n); 150 sp += n; 151 printf("after "); 152 printwhere(prevline, srcfilename(pc)); 153 printf(":\t"); 154 prtree(p); 155 printf(" = "); 156 printval(p->nodetype); 157 putchar('\n'); 158 if (tp->trtype == TRSTOP) { 159 isstopped = TRUE; 160 curline = srcline(pc); 161 printstatus(); 162 } 163 } 164 } 165 prevline = curline; 166 } 167 168 /* 169 * Free the table. Note that trvar and trcond fields are not freed, 170 * this is because they are the same as in the breakpoint table and 171 * are freed by the bpfree routine. 172 */ 173 174 trfree() 175 { 176 register TRINFO *tp, *next; 177 178 for (tp = trhead; tp != NIL; tp = next) { 179 next = tp->trnext; 180 if (tp->trvalue != NIL) { 181 free(tp->trvalue); 182 } 183 free(tp); 184 } 185 trhead = NIL; 186 } 187