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