Blame


1 0a61c07d 2004-04-19 devnull // poor emulation of SVR5 truss command - traces system calls
2 0a61c07d 2004-04-19 devnull
3 d0f7912a 2004-04-21 devnull include("syscall");
4 0a61c07d 2004-04-19 devnull
5 0a61c07d 2004-04-19 devnull _stoprunning = 0;
6 0a61c07d 2004-04-19 devnull
7 0a61c07d 2004-04-19 devnull defn stopped(pid) {
8 0a61c07d 2004-04-19 devnull local l;
9 0a61c07d 2004-04-19 devnull local pc;
10 0a61c07d 2004-04-19 devnull pc = *PC;
11 0a61c07d 2004-04-19 devnull if notes then {
12 0a61c07d 2004-04-19 devnull if (notes[0]!="sys: breakpoint") then
13 0a61c07d 2004-04-19 devnull {
14 0a61c07d 2004-04-19 devnull print(pid,": ",trapreason(),"\t");
15 0a61c07d 2004-04-19 devnull print(fmt(pc,97),"\t",fmt(pc,105),"\n");
16 0a61c07d 2004-04-19 devnull print("Notes pending:\n");
17 0a61c07d 2004-04-19 devnull l = notes;
18 0a61c07d 2004-04-19 devnull while l do
19 0a61c07d 2004-04-19 devnull {
20 0a61c07d 2004-04-19 devnull print("\t",head l,"\n");
21 0a61c07d 2004-04-19 devnull l = tail l;
22 0a61c07d 2004-04-19 devnull }
23 0a61c07d 2004-04-19 devnull _stoprunning = 1;
24 0a61c07d 2004-04-19 devnull }
25 0a61c07d 2004-04-19 devnull }
26 0a61c07d 2004-04-19 devnull }
27 0a61c07d 2004-04-19 devnull
28 0a61c07d 2004-04-19 devnull defn _addressof(pattern) {
29 0a61c07d 2004-04-19 devnull local s, l;
30 0a61c07d 2004-04-19 devnull l = symbols;
31 0a61c07d 2004-04-19 devnull pattern = "^\\$*"+pattern+"$";
32 0a61c07d 2004-04-19 devnull while l do
33 0a61c07d 2004-04-19 devnull {
34 0a61c07d 2004-04-19 devnull s = head l;
35 0a61c07d 2004-04-19 devnull if regexp(pattern, s[0]) && ((s[1] == 'T') || (s[1] == 'L')) then
36 0a61c07d 2004-04-19 devnull return s[2];
37 0a61c07d 2004-04-19 devnull l = tail l;
38 0a61c07d 2004-04-19 devnull }
39 0a61c07d 2004-04-19 devnull return 0;
40 0a61c07d 2004-04-19 devnull }
41 0a61c07d 2004-04-19 devnull
42 0a61c07d 2004-04-19 devnull stopPC = {};
43 0a61c07d 2004-04-19 devnull readPC = {};
44 0a61c07d 2004-04-19 devnull fd2pathPC = {};
45 0a61c07d 2004-04-19 devnull errstrPC = {};
46 0a61c07d 2004-04-19 devnull awaitPC = {};
47 0a61c07d 2004-04-19 devnull _waitPC = {};
48 0a61c07d 2004-04-19 devnull _errstrPC = {};
49 0a61c07d 2004-04-19 devnull trusscalls = {
50 0a61c07d 2004-04-19 devnull "sysr1",
51 0a61c07d 2004-04-19 devnull "_errstr",
52 0a61c07d 2004-04-19 devnull "bind",
53 0a61c07d 2004-04-19 devnull "chdir",
54 0a61c07d 2004-04-19 devnull "close",
55 0a61c07d 2004-04-19 devnull "dup",
56 0a61c07d 2004-04-19 devnull "alarm",
57 0a61c07d 2004-04-19 devnull "exec",
58 0a61c07d 2004-04-19 devnull "_exits",
59 0a61c07d 2004-04-19 devnull "_fsession",
60 0a61c07d 2004-04-19 devnull "fauth",
61 0a61c07d 2004-04-19 devnull "_fstat",
62 0a61c07d 2004-04-19 devnull "segbrk",
63 0a61c07d 2004-04-19 devnull "_mount",
64 0a61c07d 2004-04-19 devnull "open",
65 0a61c07d 2004-04-19 devnull "_read",
66 0a61c07d 2004-04-19 devnull "oseek",
67 0a61c07d 2004-04-19 devnull "sleep",
68 0a61c07d 2004-04-19 devnull "_stat",
69 0a61c07d 2004-04-19 devnull "rfork",
70 0a61c07d 2004-04-19 devnull "_write",
71 0a61c07d 2004-04-19 devnull "pipe",
72 0a61c07d 2004-04-19 devnull "create",
73 0a61c07d 2004-04-19 devnull "fd2path",
74 0a61c07d 2004-04-19 devnull "brk_",
75 0a61c07d 2004-04-19 devnull "remove",
76 0a61c07d 2004-04-19 devnull "_wstat",
77 0a61c07d 2004-04-19 devnull "_fwstat",
78 0a61c07d 2004-04-19 devnull "notify",
79 0a61c07d 2004-04-19 devnull "noted",
80 0a61c07d 2004-04-19 devnull "segattach",
81 0a61c07d 2004-04-19 devnull "segdetach",
82 0a61c07d 2004-04-19 devnull "segfree",
83 0a61c07d 2004-04-19 devnull "segflush",
84 0a61c07d 2004-04-19 devnull "rendezvous",
85 0a61c07d 2004-04-19 devnull "unmount",
86 0a61c07d 2004-04-19 devnull "_wait",
87 0a61c07d 2004-04-19 devnull "seek",
88 0a61c07d 2004-04-19 devnull "fversion",
89 0a61c07d 2004-04-19 devnull "errstr",
90 0a61c07d 2004-04-19 devnull "stat",
91 0a61c07d 2004-04-19 devnull "fstat",
92 0a61c07d 2004-04-19 devnull "wstat",
93 0a61c07d 2004-04-19 devnull "fwstat",
94 0a61c07d 2004-04-19 devnull "mount",
95 0a61c07d 2004-04-19 devnull "await",
96 0a61c07d 2004-04-19 devnull "pread",
97 0a61c07d 2004-04-19 devnull "pwrite",
98 0a61c07d 2004-04-19 devnull };
99 0a61c07d 2004-04-19 devnull
100 0a61c07d 2004-04-19 devnull trussapecalls = {
101 0a61c07d 2004-04-19 devnull "_SYSR1",
102 0a61c07d 2004-04-19 devnull "__ERRSTR",
103 0a61c07d 2004-04-19 devnull "_BIND",
104 0a61c07d 2004-04-19 devnull "_CHDIR",
105 0a61c07d 2004-04-19 devnull "_CLOSE",
106 0a61c07d 2004-04-19 devnull "_DUP",
107 0a61c07d 2004-04-19 devnull "_ALARM",
108 0a61c07d 2004-04-19 devnull "_EXEC",
109 0a61c07d 2004-04-19 devnull "_EXITS",
110 0a61c07d 2004-04-19 devnull "__FSESSION",
111 0a61c07d 2004-04-19 devnull "_FAUTH",
112 0a61c07d 2004-04-19 devnull "__FSTAT",
113 0a61c07d 2004-04-19 devnull "_SEGBRK",
114 0a61c07d 2004-04-19 devnull "__MOUNT",
115 0a61c07d 2004-04-19 devnull "_OPEN",
116 0a61c07d 2004-04-19 devnull "__READ",
117 0a61c07d 2004-04-19 devnull "_OSEEK",
118 0a61c07d 2004-04-19 devnull "_SLEEP",
119 0a61c07d 2004-04-19 devnull "__STAT",
120 0a61c07d 2004-04-19 devnull "_RFORK",
121 0a61c07d 2004-04-19 devnull "__WRITE",
122 0a61c07d 2004-04-19 devnull "_PIPE",
123 0a61c07d 2004-04-19 devnull "_CREATE",
124 0a61c07d 2004-04-19 devnull "_FD2PATH",
125 0a61c07d 2004-04-19 devnull "_BRK_",
126 0a61c07d 2004-04-19 devnull "_REMOVE",
127 0a61c07d 2004-04-19 devnull "__WSTAT",
128 0a61c07d 2004-04-19 devnull "__FWSTAT",
129 0a61c07d 2004-04-19 devnull "_NOTIFY",
130 0a61c07d 2004-04-19 devnull "_NOTED",
131 0a61c07d 2004-04-19 devnull "_SEGATTACH",
132 0a61c07d 2004-04-19 devnull "_SEGDETACH",
133 0a61c07d 2004-04-19 devnull "_SEGFREE",
134 0a61c07d 2004-04-19 devnull "_SEGFLUSH",
135 0a61c07d 2004-04-19 devnull "_RENDEZVOUS",
136 0a61c07d 2004-04-19 devnull "_UNMOUNT",
137 0a61c07d 2004-04-19 devnull "__WAIT",
138 0a61c07d 2004-04-19 devnull "_SEEK",
139 0a61c07d 2004-04-19 devnull "__NFVERSION",
140 0a61c07d 2004-04-19 devnull "__NERRSTR",
141 0a61c07d 2004-04-19 devnull "_STAT",
142 0a61c07d 2004-04-19 devnull "__NFSTAT",
143 0a61c07d 2004-04-19 devnull "__NWSTAT",
144 0a61c07d 2004-04-19 devnull "__NFWSTAT",
145 0a61c07d 2004-04-19 devnull "__NMOUNT",
146 0a61c07d 2004-04-19 devnull "__NAWAIT",
147 0a61c07d 2004-04-19 devnull "_PREAD",
148 0a61c07d 2004-04-19 devnull "_PWRITE",
149 0a61c07d 2004-04-19 devnull };
150 0a61c07d 2004-04-19 devnull
151 0a61c07d 2004-04-19 devnull defn addressof(pattern) {
152 0a61c07d 2004-04-19 devnull // translate to ape system calls if we have an ape binary
153 0a61c07d 2004-04-19 devnull if _addressof("_EXITS") == 0 then
154 0a61c07d 2004-04-19 devnull return _addressof(pattern);
155 0a61c07d 2004-04-19 devnull return _addressof(trussapecalls[match(pattern, trusscalls)]);
156 0a61c07d 2004-04-19 devnull }
157 0a61c07d 2004-04-19 devnull
158 0a61c07d 2004-04-19 devnull defn setuptruss() {
159 0a61c07d 2004-04-19 devnull local lst, offset, name, addr;
160 0a61c07d 2004-04-19 devnull
161 0a61c07d 2004-04-19 devnull trussbpt = {};
162 0a61c07d 2004-04-19 devnull offset = trapoffset();
163 0a61c07d 2004-04-19 devnull lst = trusscalls;
164 0a61c07d 2004-04-19 devnull while lst do
165 0a61c07d 2004-04-19 devnull {
166 0a61c07d 2004-04-19 devnull name = head lst;
167 0a61c07d 2004-04-19 devnull lst = tail lst;
168 0a61c07d 2004-04-19 devnull addr = addressof(name);
169 0a61c07d 2004-04-19 devnull if addr then
170 0a61c07d 2004-04-19 devnull {
171 0a61c07d 2004-04-19 devnull bpset(addr+offset);
172 0a61c07d 2004-04-19 devnull trussbpt = append trussbpt, (addr+offset);
173 0a61c07d 2004-04-19 devnull // sometimes _exits is renamed $_exits
174 0a61c07d 2004-04-19 devnull if(regexp("exits|exec", name)) then stopPC = append stopPC, (addr+offset);
175 0a61c07d 2004-04-19 devnull if(regexp("read", name)) then readPC = append readPC, (addr+offset);
176 0a61c07d 2004-04-19 devnull if(regexp("fd2path", name)) then fd2pathPC = append fd2pathPC, (addr+offset);
177 0a61c07d 2004-04-19 devnull if(regexp("^\\$*await", name)) then awaitPC = append awaitPC, (addr+offset);
178 0a61c07d 2004-04-19 devnull if(regexp("^\\$*errstr", name)) then errstrPC = append errstrPC, (addr+offset);
179 0a61c07d 2004-04-19 devnull // compatibility hacks for old kernel
180 0a61c07d 2004-04-19 devnull if(regexp("_wait", name)) then _waitPC = append _waitPC, (addr+offset);
181 0a61c07d 2004-04-19 devnull if(regexp("_errstr", name)) then _errstrPC = append _errstrPC, (addr+offset);
182 0a61c07d 2004-04-19 devnull }
183 0a61c07d 2004-04-19 devnull }
184 0a61c07d 2004-04-19 devnull }
185 0a61c07d 2004-04-19 devnull
186 0a61c07d 2004-04-19 devnull defn trussflush() {
187 0a61c07d 2004-04-19 devnull stop(pid); // already stopped, but flushes output
188 0a61c07d 2004-04-19 devnull }
189 0a61c07d 2004-04-19 devnull
190 0a61c07d 2004-04-19 devnull defn new() {
191 0a61c07d 2004-04-19 devnull bplist = {};
192 0a61c07d 2004-04-19 devnull newproc(progargs);
193 0a61c07d 2004-04-19 devnull bpset(follow(main)[0]);
194 0a61c07d 2004-04-19 devnull cont();
195 0a61c07d 2004-04-19 devnull bpdel(*PC);
196 0a61c07d 2004-04-19 devnull // clear the hang bit, which is left set by newproc, so programs we fork/exec don't hang
197 0a61c07d 2004-04-19 devnull printto("/proc/"+itoa(pid)+"/ctl", "nohang");
198 0a61c07d 2004-04-19 devnull }
199 0a61c07d 2004-04-19 devnull
200 0a61c07d 2004-04-19 devnull defn truss() {
201 0a61c07d 2004-04-19 devnull local pc, lst, offset, prevpc, pcspret, ret;
202 0a61c07d 2004-04-19 devnull
203 0a61c07d 2004-04-19 devnull offset = trapoffset();
204 0a61c07d 2004-04-19 devnull
205 0a61c07d 2004-04-19 devnull stop(pid);
206 0a61c07d 2004-04-19 devnull _stoprunning = 0;
207 0a61c07d 2004-04-19 devnull setuptruss();
208 0a61c07d 2004-04-19 devnull pcspret = UPCSPRET();
209 0a61c07d 2004-04-19 devnull
210 0a61c07d 2004-04-19 devnull while !_stoprunning do {
211 0a61c07d 2004-04-19 devnull cont();
212 0a61c07d 2004-04-19 devnull if notes[0]!="sys: breakpoint" then {
213 0a61c07d 2004-04-19 devnull cleantruss();
214 0a61c07d 2004-04-19 devnull return {};
215 0a61c07d 2004-04-19 devnull }
216 0a61c07d 2004-04-19 devnull pc = *PC;
217 0a61c07d 2004-04-19 devnull if match(*PC, stopPC)>=0 then {
218 0a61c07d 2004-04-19 devnull print(pid,": ",trapreason(),"\t");
219 0a61c07d 2004-04-19 devnull print(fmt(pc,'a'),"\t",fmt(pc,'i'),"\n");
220 0a61c07d 2004-04-19 devnull cleantruss();
221 0a61c07d 2004-04-19 devnull return {};
222 0a61c07d 2004-04-19 devnull }
223 0a61c07d 2004-04-19 devnull if match(*PC, trussbpt)>=0 then {
224 0a61c07d 2004-04-19 devnull usyscall();
225 0a61c07d 2004-04-19 devnull trussflush();
226 0a61c07d 2004-04-19 devnull prevpc = *PC;
227 0a61c07d 2004-04-19 devnull step();
228 0a61c07d 2004-04-19 devnull ret = eval pcspret[2];
229 0a61c07d 2004-04-19 devnull print("\treturn value: ", ret\D, "\n");
230 0a61c07d 2004-04-19 devnull if (ret>=0) && (match(prevpc, readPC)>=0) then {
231 0a61c07d 2004-04-19 devnull print("\tdata: ");
232 0a61c07d 2004-04-19 devnull printtextordata(*((eval pcspret[1])+4), ret);
233 0a61c07d 2004-04-19 devnull print("\n");
234 0a61c07d 2004-04-19 devnull }
235 0a61c07d 2004-04-19 devnull if (ret>=0) && (match(prevpc, fd2pathPC)>=0) then {
236 0a61c07d 2004-04-19 devnull print("\tdata: \"", *(*((eval pcspret[1])+4)\s), "\"\n");
237 0a61c07d 2004-04-19 devnull }
238 0a61c07d 2004-04-19 devnull if (ret>=0) && (match(prevpc, errstrPC)>=0) then {
239 0a61c07d 2004-04-19 devnull print("\tdata: \"", *(*(eval pcspret[1])\s), "\"\n");
240 0a61c07d 2004-04-19 devnull }
241 0a61c07d 2004-04-19 devnull if (ret>=0) && (match(prevpc, awaitPC)>=0) then {
242 0a61c07d 2004-04-19 devnull print("\tdata: ");
243 0a61c07d 2004-04-19 devnull printtextordata(*(eval pcspret[1]), ret);
244 0a61c07d 2004-04-19 devnull print("\n");
245 0a61c07d 2004-04-19 devnull }
246 0a61c07d 2004-04-19 devnull // compatibility hacks for old kernel:
247 0a61c07d 2004-04-19 devnull if (ret>=0) && (match(prevpc, _waitPC)>=0) then {
248 0a61c07d 2004-04-19 devnull print("\tdata: ");
249 0a61c07d 2004-04-19 devnull printtextordata(*(eval pcspret[1]), 12+3*12+64);
250 0a61c07d 2004-04-19 devnull print("\n");
251 0a61c07d 2004-04-19 devnull }
252 0a61c07d 2004-04-19 devnull if (ret>=0) && (match(prevpc, _errstrPC)>=0) then {
253 0a61c07d 2004-04-19 devnull print("\tdata: ");
254 0a61c07d 2004-04-19 devnull printtextordata(*(eval pcspret[1]), 64);
255 0a61c07d 2004-04-19 devnull print("\n");
256 0a61c07d 2004-04-19 devnull }
257 0a61c07d 2004-04-19 devnull }
258 0a61c07d 2004-04-19 devnull trussflush();
259 0a61c07d 2004-04-19 devnull }
260 0a61c07d 2004-04-19 devnull }
261 0a61c07d 2004-04-19 devnull
262 0a61c07d 2004-04-19 devnull defn cleantruss() {
263 0a61c07d 2004-04-19 devnull local lst, offset, addr;
264 0a61c07d 2004-04-19 devnull
265 0a61c07d 2004-04-19 devnull stop(pid);
266 0a61c07d 2004-04-19 devnull offset = trapoffset();
267 0a61c07d 2004-04-19 devnull lst = trussbpt;
268 0a61c07d 2004-04-19 devnull while lst do
269 0a61c07d 2004-04-19 devnull {
270 0a61c07d 2004-04-19 devnull addr = head lst;
271 0a61c07d 2004-04-19 devnull lst = tail lst;
272 0a61c07d 2004-04-19 devnull bpdel(addr);
273 0a61c07d 2004-04-19 devnull }
274 0a61c07d 2004-04-19 devnull trussbpt = {};
275 0a61c07d 2004-04-19 devnull **PC = @*PC; // repair current instruction
276 0a61c07d 2004-04-19 devnull }
277 0a61c07d 2004-04-19 devnull
278 0a61c07d 2004-04-19 devnull defn untruss() {
279 0a61c07d 2004-04-19 devnull cleantruss();
280 0a61c07d 2004-04-19 devnull start(pid);
281 0a61c07d 2004-04-19 devnull }
282 0a61c07d 2004-04-19 devnull
283 d0f7912a 2004-04-21 devnull print(acidfile);