Blob


1 // trace user malloc pool - trace malloc, realloc, and free calls
2 // if trumpsbrk is set, we trace sbrkalloc and sbrkmerge too.
4 _stoprunning = 0;
5 trumphexaddrs = 0;
6 trumpsbrk = 0;
8 defn stopped(pid) {
9 local l;
10 local pc;
11 pc = *PC;
12 if notes then {
13 if (notes[0]!="sys: breakpoint") then
14 {
15 print(pid,": ",reason(*TRAP),"\t");
16 print(fmt(pc,97),"\t",fmt(pc,105),"\n");
17 print("Notes pending:\n");
18 l = notes;
19 while l do
20 {
21 print("\t",head l,"\n");
22 l = tail l;
23 }
24 _stoprunning = 1;
25 }
26 }
27 }
29 defn printstack() {
30 local frame, stk, pcs, lst, x;
32 pcs = {*PC};
33 stk = strace(*PC,*SP,0);
34 while stk do {
35 pcs = append pcs, stk[0][1];
36 stk = tail stk;
37 }
39 print(" #");
40 lst = pcs;
41 while lst do {
42 if trumphexaddrs != 0 then
43 x = lst[0]\X;
44 else
45 x = lst[0]\a;
46 print(" src(", x, ");");
47 lst = tail lst;
48 }
49 print("\n");
50 }
52 defn setuptrump() {
53 mallocPC = malloc;
54 malloczPC = mallocz;
55 freePC = free;
56 reallocPC = realloc;
57 sbrkallocPC = sbrkalloc;
58 sbrkmergePC = sbrkmerge;
60 // linker might fill delay slot with first instruction
61 if objtype == "mips" then {
62 mallocPC = mallocPC+4;
63 malloczPC = malloczPC+4;
64 freePC = freePC+4;
65 reallocPC = reallocPC+4;
66 sbrkallocPC = sbrkallocPC+4;
67 sbrkmergePC = sbrkmergePC+4;
68 }
70 bpset(mallocPC);
71 bpset(malloczPC);
72 bpset(freePC);
73 bpset(reallocPC);
74 if trumpsbrk then {
75 bpset(sbrkallocPC);
76 bpset(sbrkmergePC);
77 }
78 }
80 defn cleantrump() {
81 stop(pid);
83 bpdel(mallocPC);
84 bpdel(malloczPC);
85 bpdel(freePC);
86 bpdel(reallocPC);
87 bpdel(sbrkallocPC);
88 bpdel(sbrkmergePC);
89 }
91 defn trumpflush() {
92 stop(pid); // already stopped, but flushes output
93 }
95 defn new() {
96 bplist = {};
97 newproc(progargs);
98 bpset(follow(main)[0]);
99 cont();
100 bpdel(*PC);
101 // clear the hang bit, which is left set by newproc, so programs we fork/exec don't hang
102 printto("/proc/"+itoa(pid)+"/ctl", "nohang");
105 defn trumpfninfo() {
106 local arg0, arg1, stk, retpc, params;
108 stk = strace(*PC, *SP, 0);
109 retpc = stk[0][1];
110 params = stk[0][2];
111 arg0 = params[0][1];
112 arg1 = 0;
113 if tail params != {} then
114 arg1 = params[1][1];
115 return {arg0, arg1, retpc};
118 defn trumpretval() {
119 if objtype=="386" then
120 return *AX;
121 if objtype=="mips" then
122 return *R1;
123 if objtype=="power" || objtype=="alpha" then
124 return *R0;
127 defn trump() {
128 local arg0, arg1, pc, ret, x;
130 stop(pid);
131 _stoprunning = 0;
132 setuptrump();
133 while !_stoprunning do {
134 cont();
135 if notes[0]!="sys: breakpoint" then {
136 cleantrump();
137 return {};
140 pc = *PC;
141 x = trumpfninfo();
142 arg0 = x[0];
143 if pc == reallocPC || pc == sbrkmergePC then
144 arg1 = x[1];
145 bpset(x[2]);
146 cont();
147 bpdel(x[2]);
148 ret = trumpretval();
149 if pc == mallocPC then
150 print(ret\X, " malloc ", arg0\D);
151 if pc == malloczPC then
152 print(ret\X, " mallocz ", arg0\D);
153 if pc == freePC then
154 print(arg0\X, " free");
155 if pc == reallocPC then
156 print(ret\X, " realloc ", arg0\X, " ", arg1\D);
157 if pc == sbrkallocPC then
158 print(ret\X, " sbrkalloc ", arg0\D);
159 if pc == sbrkmergePC then
160 print("sbrkmerge ", arg0\X, " ", arg1\X, " = ", ret\D);
161 printstack();
162 trumpflush();
166 defn untrump() {
167 cleantrump();
168 start(pid);
171 print(acidfile);