1 /*-
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)trinfo.c 8.1 (Berkeley) 06/06/93";
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
addvar(trtype,node,cond)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
delvar(trtype,node,cond)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
prvarnews()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
trfree()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