1*48103Sbostic /*- 2*48103Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48103Sbostic * All rights reserved. 4*48103Sbostic * 5*48103Sbostic * %sccs.include.redist.c% 622282Sdist */ 75470Slinton 822282Sdist #ifndef lint 9*48103Sbostic static char sccsid[] = "@(#)trinfo.c 5.3 (Berkeley) 04/16/91"; 10*48103Sbostic #endif /* not lint */ 115470Slinton 125470Slinton /* 135470Slinton * Trace information management. 145470Slinton * 155470Slinton * The trace information is a list of variables that are being 165470Slinton * traced or whose value changing should cause a stop. 175470Slinton */ 185470Slinton 195470Slinton #include "defs.h" 205470Slinton #include "breakpoint.h" 215470Slinton #include "process.h" 225470Slinton #include "machine.h" 235470Slinton #include "sym.h" 245470Slinton #include "tree.h" 255470Slinton #include "source.h" 265470Slinton #include "object.h" 275470Slinton #include "tree/tree.rep" 2830843Smckusick #include "process/process.rep" 2930843Smckusick #include "process/pxinfo.h" 305470Slinton 315470Slinton /* 325470Slinton * When tracing variables we keep a copy of their most recent value 335470Slinton * and compare it to the current one each time a breakpoint occurs. 345470Slinton * MAXTRSIZE is the maximum size variable we allow. 355470Slinton */ 365470Slinton 375470Slinton #define MAXTRSIZE 512 385470Slinton 395470Slinton /* 405470Slinton * The tracing structure is a list of information about all the 415470Slinton * variables that are being traced. 425470Slinton */ 435470Slinton 445470Slinton typedef struct trinfo { 455760Slinton TRTYPE trtype; 465760Slinton ADDRESS traddr; 475760Slinton SYM *trblock; 485760Slinton NODE *trvar; 495760Slinton NODE *trcond; 505760Slinton char *trvalue; 515760Slinton struct trinfo *trnext; 525470Slinton } TRINFO; 535470Slinton 545470Slinton LOCAL TRINFO *trhead; 555470Slinton 565470Slinton /* 575470Slinton * add a variable to be traced 585470Slinton */ 595470Slinton 605470Slinton addvar(trtype, node, cond) 615470Slinton TRTYPE trtype; 625470Slinton NODE *node; 635470Slinton NODE *cond; 645470Slinton { 655760Slinton register TRINFO *tp; 665470Slinton 675760Slinton tp = alloc(1, TRINFO); 685760Slinton tp->trtype = trtype; 695760Slinton tp->traddr = (ADDRESS) -1; 705760Slinton tp->trblock = curfunc; 715760Slinton tp->trvar = node; 725760Slinton tp->trcond = cond; 735760Slinton tp->trvalue = NIL; 745760Slinton tp->trnext = trhead; 755760Slinton trhead = tp; 765470Slinton } 775470Slinton 785470Slinton /* 795470Slinton * remove a variable from the trace list 805470Slinton */ 815470Slinton 825470Slinton delvar(trtype, node, cond) 835470Slinton TRTYPE trtype; 845470Slinton NODE *node; 855470Slinton NODE *cond; 865470Slinton { 875760Slinton register TRINFO *tp, *last; 885470Slinton 895760Slinton last = NIL; 905760Slinton for (tp = trhead; tp != NIL; tp = tp->trnext) { 915760Slinton if (tp->trtype == trtype && 925760Slinton tr_equal(tp->trvar, node) && 935760Slinton tr_equal(tp->trcond, cond)) { 945760Slinton break; 955470Slinton } 965760Slinton } 975760Slinton if (tp == NIL) { 985760Slinton trerror("can't delete term %t", node); 995760Slinton } 1005760Slinton if (last == NIL) { 1015760Slinton trhead = tp->trnext; 1025760Slinton } else { 1035760Slinton last->trnext = tp->trnext; 1045760Slinton } 1055760Slinton if (tp->trvalue != NIL) { 1065760Slinton free(tp->trvalue); 1075760Slinton } 1085760Slinton free(tp); 1095470Slinton } 1105470Slinton 1115470Slinton /* 1125470Slinton * Print out any news about variables in the list whose 1135470Slinton * values have changed. 1145470Slinton */ 1155470Slinton 1165470Slinton prvarnews() 1175470Slinton { 1185760Slinton register TRINFO *tp; 1195760Slinton register NODE *p; 1205760Slinton register int n; 1215760Slinton SYM *s; 1225760Slinton char buff[MAXTRSIZE]; 1235760Slinton static LINENO prevline; 1245470Slinton 1255760Slinton for (tp = trhead; tp != NIL; tp = tp->trnext) { 1265760Slinton if (tp->trcond != NIL && !cond(tp->trcond)) { 1275760Slinton continue; 1285470Slinton } 1295760Slinton s = curfunc; 1305760Slinton while (s != NIL && s != tp->trblock) { 1315760Slinton s = container(s); 1325760Slinton } 1335760Slinton if (s == NIL) { 1345760Slinton continue; 1355760Slinton } 1365760Slinton p = tp->trvar; 1375760Slinton if (tp->traddr == (ADDRESS) -1) { 1385760Slinton tp->traddr = lval(p->left); 1395760Slinton } 1405760Slinton n = size(p->nodetype); 1415760Slinton dread(buff, tp->traddr, n); 1425760Slinton if (tp->trvalue == NIL) { 1435760Slinton tp->trvalue = alloc(n, char); 1445760Slinton mov(buff, tp->trvalue, n); 1455760Slinton mov(buff, sp, n); 1465760Slinton sp += n; 14730843Smckusick #ifdef tahoe 14830843Smckusick alignstack(); 14930843Smckusick #endif 1505760Slinton if (tp->trtype == TRPRINT) { 1515760Slinton printf("initially (at "); 1525760Slinton printwhere(curline, srcfilename(pc)); 1535760Slinton printf("):\t"); 1545760Slinton prtree(p); 1555760Slinton printf(" = "); 1565760Slinton printval(p->nodetype); 1575760Slinton putchar('\n'); 1585760Slinton } 1595760Slinton } else if (cmp(tp->trvalue, buff, n) != 0) { 1605760Slinton mov(buff, tp->trvalue, n); 1615760Slinton mov(buff, sp, n); 1625760Slinton sp += n; 16330843Smckusick #ifdef tahoe 16430843Smckusick alignstack(); 16530843Smckusick #endif 1665760Slinton printf("after "); 1675760Slinton printwhere(prevline, srcfilename(pc)); 1685760Slinton printf(":\t"); 1695760Slinton prtree(p); 1705760Slinton printf(" = "); 1715760Slinton printval(p->nodetype); 1725760Slinton putchar('\n'); 1735760Slinton if (tp->trtype == TRSTOP) { 1745760Slinton isstopped = TRUE; 1755760Slinton curline = srcline(pc); 1765760Slinton printstatus(); 1775760Slinton } 1785760Slinton } 1795760Slinton } 1805760Slinton prevline = curline; 1815470Slinton } 1825470Slinton 1835470Slinton /* 1845470Slinton * Free the table. Note that trvar and trcond fields are not freed, 1855470Slinton * this is because they are the same as in the breakpoint table and 1865470Slinton * are freed by the bpfree routine. 1875470Slinton */ 1885470Slinton 1895470Slinton trfree() 1905470Slinton { 1915760Slinton register TRINFO *tp, *next; 1925470Slinton 1935760Slinton for (tp = trhead; tp != NIL; tp = next) { 1945760Slinton next = tp->trnext; 1955760Slinton if (tp->trvalue != NIL) { 1965760Slinton free(tp->trvalue); 1975470Slinton } 1985760Slinton free(tp); 1995760Slinton } 2005760Slinton trhead = NIL; 2015470Slinton } 202