1 0a61c07d 2004-04-19 devnull // poor emulation of SVR5 truss command - traces system calls
3 d0f7912a 2004-04-21 devnull include("syscall");
5 0a61c07d 2004-04-19 devnull _stoprunning = 0;
7 0a61c07d 2004-04-19 devnull defn stopped(pid) {
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
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
20 0a61c07d 2004-04-19 devnull print("\t",head l,"\n");
21 0a61c07d 2004-04-19 devnull l = tail l;
23 0a61c07d 2004-04-19 devnull _stoprunning = 1;
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
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;
39 0a61c07d 2004-04-19 devnull return 0;
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 = {
51 0a61c07d 2004-04-19 devnull "_errstr",
58 0a61c07d 2004-04-19 devnull "_exits",
59 0a61c07d 2004-04-19 devnull "_fsession",
61 0a61c07d 2004-04-19 devnull "_fstat",
62 0a61c07d 2004-04-19 devnull "segbrk",
63 0a61c07d 2004-04-19 devnull "_mount",
70 0a61c07d 2004-04-19 devnull "_write",
72 0a61c07d 2004-04-19 devnull "create",
73 0a61c07d 2004-04-19 devnull "fd2path",
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",
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",
88 0a61c07d 2004-04-19 devnull "fversion",
89 0a61c07d 2004-04-19 devnull "errstr",
93 0a61c07d 2004-04-19 devnull "fwstat",
97 0a61c07d 2004-04-19 devnull "pwrite",
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",
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",
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)]);
158 0a61c07d 2004-04-19 devnull defn setuptruss() {
159 0a61c07d 2004-04-19 devnull local lst, offset, name, addr;
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
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
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);
186 0a61c07d 2004-04-19 devnull defn trussflush() {
187 0a61c07d 2004-04-19 devnull stop(pid); // already stopped, but flushes output
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]);
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");
200 0a61c07d 2004-04-19 devnull defn truss() {
201 0a61c07d 2004-04-19 devnull local pc, lst, offset, prevpc, pcspret, ret;
203 0a61c07d 2004-04-19 devnull offset = trapoffset();
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();
210 0a61c07d 2004-04-19 devnull while !_stoprunning do {
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 {};
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 {};
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;
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");
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");
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");
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");
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");
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");
258 0a61c07d 2004-04-19 devnull trussflush();
262 0a61c07d 2004-04-19 devnull defn cleantruss() {
263 0a61c07d 2004-04-19 devnull local lst, offset, addr;
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
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);
274 0a61c07d 2004-04-19 devnull trussbpt = {};
275 0a61c07d 2004-04-19 devnull **PC = @*PC; // repair current instruction
278 0a61c07d 2004-04-19 devnull defn untruss() {
279 0a61c07d 2004-04-19 devnull cleantruss();
280 0a61c07d 2004-04-19 devnull start(pid);
283 d0f7912a 2004-04-21 devnull print(acidfile);