Blame


1 a84cbb2a 2004-04-19 devnull /*
2 a84cbb2a 2004-04-19 devnull * process interface for Linux.
3 a84cbb2a 2004-04-19 devnull *
4 a84cbb2a 2004-04-19 devnull * Uses ptrace for registers and data,
5 a84cbb2a 2004-04-19 devnull * /proc for some process status.
6 a84cbb2a 2004-04-19 devnull * There's not much point to worrying about
7 a84cbb2a 2004-04-19 devnull * byte order here -- using ptrace means
8 a84cbb2a 2004-04-19 devnull * we're running on the architecture we're debugging,
9 a84cbb2a 2004-04-19 devnull * unless truly weird stuff is going on.
10 a84cbb2a 2004-04-19 devnull *
11 a84cbb2a 2004-04-19 devnull * It is tempting to use /proc/%d/mem along with
12 a84cbb2a 2004-04-19 devnull * the sp and pc in the stat file to get a stack trace
13 a84cbb2a 2004-04-19 devnull * without attaching to the program, but unfortunately
14 a84cbb2a 2004-04-19 devnull * you can't read the mem file unless you've attached.
15 a84cbb2a 2004-04-19 devnull */
16 a84cbb2a 2004-04-19 devnull
17 a84cbb2a 2004-04-19 devnull #include <u.h>
18 a84cbb2a 2004-04-19 devnull #include <sys/ptrace.h>
19 a84cbb2a 2004-04-19 devnull #include <sys/types.h>
20 a84cbb2a 2004-04-19 devnull #include <sys/wait.h>
21 a84cbb2a 2004-04-19 devnull #include <signal.h>
22 a84cbb2a 2004-04-19 devnull #include <errno.h>
23 a84cbb2a 2004-04-19 devnull #include <libc.h>
24 a84cbb2a 2004-04-19 devnull #include <mach.h>
25 a84cbb2a 2004-04-19 devnull #include "ureg386.h"
26 a84cbb2a 2004-04-19 devnull
27 a84cbb2a 2004-04-19 devnull Mach *machcpu = &mach386;
28 a84cbb2a 2004-04-19 devnull
29 a84cbb2a 2004-04-19 devnull typedef struct PtraceRegs PtraceRegs;
30 a84cbb2a 2004-04-19 devnull
31 a84cbb2a 2004-04-19 devnull struct PtraceRegs
32 a84cbb2a 2004-04-19 devnull {
33 a84cbb2a 2004-04-19 devnull Regs r;
34 a84cbb2a 2004-04-19 devnull int pid;
35 a84cbb2a 2004-04-19 devnull };
36 a84cbb2a 2004-04-19 devnull
37 4f0073fe 2004-06-11 devnull static int ptracerw(Map*, Seg*, ulong, void*, uint, int);
38 4f0073fe 2004-06-11 devnull static int ptraceregrw(Regs*, char*, ulong*, int);
39 a84cbb2a 2004-04-19 devnull
40 2e965b33 2004-05-05 devnull static int attachedpids[1000];
41 2e965b33 2004-05-05 devnull static int nattached;
42 2e965b33 2004-05-05 devnull
43 a84cbb2a 2004-04-19 devnull void
44 a84cbb2a 2004-04-19 devnull unmapproc(Map *map)
45 a84cbb2a 2004-04-19 devnull {
46 a84cbb2a 2004-04-19 devnull int i;
47 a84cbb2a 2004-04-19 devnull
48 a84cbb2a 2004-04-19 devnull if(map == nil)
49 a84cbb2a 2004-04-19 devnull return;
50 a84cbb2a 2004-04-19 devnull for(i=0; i<map->nseg; i++)
51 a84cbb2a 2004-04-19 devnull while(i<map->nseg && map->seg[i].pid){
52 a84cbb2a 2004-04-19 devnull map->nseg--;
53 a84cbb2a 2004-04-19 devnull memmove(&map->seg[i], &map->seg[i+1],
54 a84cbb2a 2004-04-19 devnull (map->nseg-i)*sizeof(map->seg[0]));
55 a84cbb2a 2004-04-19 devnull }
56 a84cbb2a 2004-04-19 devnull }
57 a84cbb2a 2004-04-19 devnull
58 a84cbb2a 2004-04-19 devnull int
59 a84cbb2a 2004-04-19 devnull mapproc(int pid, Map *map, Regs **rp)
60 a84cbb2a 2004-04-19 devnull {
61 2e965b33 2004-05-05 devnull int i;
62 a84cbb2a 2004-04-19 devnull Seg s;
63 a84cbb2a 2004-04-19 devnull PtraceRegs *r;
64 a84cbb2a 2004-04-19 devnull
65 2e965b33 2004-05-05 devnull if(nattached==1 && attachedpids[0] == pid)
66 2e965b33 2004-05-05 devnull goto already;
67 2e965b33 2004-05-05 devnull if(nattached)
68 2e965b33 2004-05-05 devnull detachproc(attachedpids[0]);
69 2e965b33 2004-05-05 devnull
70 2e965b33 2004-05-05 devnull for(i=0; i<nattached; i++)
71 2e965b33 2004-05-05 devnull if(attachedpids[i]==pid)
72 2e965b33 2004-05-05 devnull goto already;
73 2e965b33 2004-05-05 devnull if(nattached == nelem(attachedpids)){
74 2e965b33 2004-05-05 devnull werrstr("attached to too many processes");
75 2e965b33 2004-05-05 devnull return -1;
76 2e965b33 2004-05-05 devnull }
77 2e965b33 2004-05-05 devnull
78 a84cbb2a 2004-04-19 devnull if(ptrace(PTRACE_ATTACH, pid, 0, 0) < 0){
79 a84cbb2a 2004-04-19 devnull werrstr("ptrace attach %d: %r", pid);
80 a84cbb2a 2004-04-19 devnull return -1;
81 a84cbb2a 2004-04-19 devnull }
82 2e965b33 2004-05-05 devnull
83 a84cbb2a 2004-04-19 devnull if(ctlproc(pid, "waitstop") < 0){
84 2e965b33 2004-05-05 devnull fprint(2, "waitstop: %r");
85 a84cbb2a 2004-04-19 devnull ptrace(PTRACE_DETACH, pid, 0, 0);
86 a84cbb2a 2004-04-19 devnull return -1;
87 a84cbb2a 2004-04-19 devnull }
88 2e965b33 2004-05-05 devnull attachedpids[nattached++] = pid;
89 a84cbb2a 2004-04-19 devnull
90 2e965b33 2004-05-05 devnull already:
91 a84cbb2a 2004-04-19 devnull memset(&s, 0, sizeof s);
92 a84cbb2a 2004-04-19 devnull s.base = 0;
93 a84cbb2a 2004-04-19 devnull s.size = 0xFFFFFFFF;
94 a84cbb2a 2004-04-19 devnull s.offset = 0;
95 a84cbb2a 2004-04-19 devnull s.name = "data";
96 a84cbb2a 2004-04-19 devnull s.file = nil;
97 a84cbb2a 2004-04-19 devnull s.rw = ptracerw;
98 a84cbb2a 2004-04-19 devnull s.pid = pid;
99 2e965b33 2004-05-05 devnull if(addseg(map, s) < 0){
100 2e965b33 2004-05-05 devnull fprint(2, "addseg: %r\n");
101 a84cbb2a 2004-04-19 devnull return -1;
102 2e965b33 2004-05-05 devnull }
103 a84cbb2a 2004-04-19 devnull
104 2e965b33 2004-05-05 devnull if((r = mallocz(sizeof(PtraceRegs), 1)) == nil){
105 2e965b33 2004-05-05 devnull fprint(2, "mallocz: %r\n");
106 a84cbb2a 2004-04-19 devnull return -1;
107 2e965b33 2004-05-05 devnull }
108 a84cbb2a 2004-04-19 devnull r->r.rw = ptraceregrw;
109 a84cbb2a 2004-04-19 devnull r->pid = pid;
110 a84cbb2a 2004-04-19 devnull *rp = (Regs*)r;
111 a84cbb2a 2004-04-19 devnull return 0;
112 a84cbb2a 2004-04-19 devnull }
113 a84cbb2a 2004-04-19 devnull
114 a84cbb2a 2004-04-19 devnull int
115 a84cbb2a 2004-04-19 devnull detachproc(int pid)
116 a84cbb2a 2004-04-19 devnull {
117 2e965b33 2004-05-05 devnull int i;
118 2e965b33 2004-05-05 devnull
119 2e965b33 2004-05-05 devnull for(i=0; i<nattached; i++){
120 2e965b33 2004-05-05 devnull if(attachedpids[i] == pid){
121 2e965b33 2004-05-05 devnull attachedpids[i] = attachedpids[--nattached];
122 2e965b33 2004-05-05 devnull break;
123 2e965b33 2004-05-05 devnull }
124 2e965b33 2004-05-05 devnull }
125 a84cbb2a 2004-04-19 devnull return ptrace(PTRACE_DETACH, pid, 0, 0);
126 a84cbb2a 2004-04-19 devnull }
127 a84cbb2a 2004-04-19 devnull
128 a84cbb2a 2004-04-19 devnull static int
129 4f0073fe 2004-06-11 devnull ptracerw(Map *map, Seg *seg, ulong addr, void *v, uint n, int isr)
130 a84cbb2a 2004-04-19 devnull {
131 a84cbb2a 2004-04-19 devnull int i;
132 a84cbb2a 2004-04-19 devnull u32int u;
133 a84cbb2a 2004-04-19 devnull uchar buf[4];
134 a84cbb2a 2004-04-19 devnull
135 a84cbb2a 2004-04-19 devnull addr += seg->base;
136 a84cbb2a 2004-04-19 devnull for(i=0; i<n; i+=4){
137 a84cbb2a 2004-04-19 devnull if(isr){
138 a84cbb2a 2004-04-19 devnull errno = 0;
139 a84cbb2a 2004-04-19 devnull u = ptrace(PTRACE_PEEKDATA, seg->pid, addr+i, 0);
140 a84cbb2a 2004-04-19 devnull if(errno)
141 a84cbb2a 2004-04-19 devnull goto ptraceerr;
142 a84cbb2a 2004-04-19 devnull if(n-i >= 4)
143 a84cbb2a 2004-04-19 devnull *(u32int*)((char*)v+i) = u;
144 a84cbb2a 2004-04-19 devnull else{
145 a84cbb2a 2004-04-19 devnull *(u32int*)buf = u;
146 a84cbb2a 2004-04-19 devnull memmove((char*)v+i, buf, n-i);
147 a84cbb2a 2004-04-19 devnull }
148 a84cbb2a 2004-04-19 devnull }else{
149 a84cbb2a 2004-04-19 devnull if(n-i >= 4)
150 a84cbb2a 2004-04-19 devnull u = *(u32int*)((char*)v+i);
151 a84cbb2a 2004-04-19 devnull else{
152 a84cbb2a 2004-04-19 devnull errno = 0;
153 a84cbb2a 2004-04-19 devnull u = ptrace(PTRACE_PEEKDATA, seg->pid, addr+i, 0);
154 a84cbb2a 2004-04-19 devnull if(errno)
155 a84cbb2a 2004-04-19 devnull return -1;
156 a84cbb2a 2004-04-19 devnull *(u32int*)buf = u;
157 a84cbb2a 2004-04-19 devnull memmove(buf, (char*)v+i, n-i);
158 a84cbb2a 2004-04-19 devnull u = *(u32int*)buf;
159 a84cbb2a 2004-04-19 devnull }
160 a84cbb2a 2004-04-19 devnull if(ptrace(PTRACE_POKEDATA, seg->pid, addr+i, &u) < 0)
161 a84cbb2a 2004-04-19 devnull goto ptraceerr;
162 a84cbb2a 2004-04-19 devnull }
163 a84cbb2a 2004-04-19 devnull }
164 a84cbb2a 2004-04-19 devnull return 0;
165 a84cbb2a 2004-04-19 devnull
166 a84cbb2a 2004-04-19 devnull ptraceerr:
167 a84cbb2a 2004-04-19 devnull werrstr("ptrace: %r");
168 a84cbb2a 2004-04-19 devnull return -1;
169 a84cbb2a 2004-04-19 devnull }
170 a84cbb2a 2004-04-19 devnull
171 a84cbb2a 2004-04-19 devnull static char* linuxregs[] = {
172 a84cbb2a 2004-04-19 devnull "BX",
173 a84cbb2a 2004-04-19 devnull "CX",
174 a84cbb2a 2004-04-19 devnull "DX",
175 a84cbb2a 2004-04-19 devnull "SI",
176 a84cbb2a 2004-04-19 devnull "DI",
177 a84cbb2a 2004-04-19 devnull "BP",
178 a84cbb2a 2004-04-19 devnull "AX",
179 a84cbb2a 2004-04-19 devnull "DS",
180 a84cbb2a 2004-04-19 devnull "ES",
181 a84cbb2a 2004-04-19 devnull "FS",
182 a84cbb2a 2004-04-19 devnull "GS",
183 a84cbb2a 2004-04-19 devnull "OAX",
184 a84cbb2a 2004-04-19 devnull "PC",
185 a84cbb2a 2004-04-19 devnull "CS",
186 a84cbb2a 2004-04-19 devnull "EFLAGS",
187 a84cbb2a 2004-04-19 devnull "SP",
188 a84cbb2a 2004-04-19 devnull "SS",
189 a84cbb2a 2004-04-19 devnull };
190 a84cbb2a 2004-04-19 devnull
191 a84cbb2a 2004-04-19 devnull static ulong
192 a84cbb2a 2004-04-19 devnull reg2linux(char *reg)
193 a84cbb2a 2004-04-19 devnull {
194 a84cbb2a 2004-04-19 devnull int i;
195 a84cbb2a 2004-04-19 devnull
196 a84cbb2a 2004-04-19 devnull for(i=0; i<nelem(linuxregs); i++)
197 a84cbb2a 2004-04-19 devnull if(strcmp(linuxregs[i], reg) == 0)
198 a84cbb2a 2004-04-19 devnull return 4*i;
199 a84cbb2a 2004-04-19 devnull return ~(ulong)0;
200 a84cbb2a 2004-04-19 devnull }
201 a84cbb2a 2004-04-19 devnull
202 a84cbb2a 2004-04-19 devnull static int
203 4f0073fe 2004-06-11 devnull ptraceregrw(Regs *regs, char *name, ulong *val, int isr)
204 a84cbb2a 2004-04-19 devnull {
205 a84cbb2a 2004-04-19 devnull int pid;
206 a84cbb2a 2004-04-19 devnull ulong addr;
207 a84cbb2a 2004-04-19 devnull u32int u;
208 a84cbb2a 2004-04-19 devnull
209 a84cbb2a 2004-04-19 devnull pid = ((PtraceRegs*)regs)->pid;
210 a84cbb2a 2004-04-19 devnull addr = reg2linux(name);
211 a84cbb2a 2004-04-19 devnull if(~addr == 0){
212 a84cbb2a 2004-04-19 devnull if(isr){
213 4f0073fe 2004-06-11 devnull *val = ~(ulong)0;
214 a84cbb2a 2004-04-19 devnull return 0;
215 a84cbb2a 2004-04-19 devnull }
216 a84cbb2a 2004-04-19 devnull werrstr("register not available");
217 a84cbb2a 2004-04-19 devnull return -1;
218 a84cbb2a 2004-04-19 devnull }
219 a84cbb2a 2004-04-19 devnull if(isr){
220 a84cbb2a 2004-04-19 devnull errno = 0;
221 a84cbb2a 2004-04-19 devnull u = ptrace(PTRACE_PEEKUSER, pid, addr, 0);
222 a84cbb2a 2004-04-19 devnull if(errno)
223 a84cbb2a 2004-04-19 devnull goto ptraceerr;
224 a84cbb2a 2004-04-19 devnull *val = u;
225 a84cbb2a 2004-04-19 devnull }else{
226 a84cbb2a 2004-04-19 devnull u = *val;
227 a84cbb2a 2004-04-19 devnull if(ptrace(PTRACE_POKEUSER, pid, addr, &u) < 0)
228 a84cbb2a 2004-04-19 devnull goto ptraceerr;
229 a84cbb2a 2004-04-19 devnull }
230 a84cbb2a 2004-04-19 devnull return 0;
231 a84cbb2a 2004-04-19 devnull
232 a84cbb2a 2004-04-19 devnull ptraceerr:
233 a84cbb2a 2004-04-19 devnull werrstr("ptrace: %r");
234 a84cbb2a 2004-04-19 devnull return -1;
235 a84cbb2a 2004-04-19 devnull }
236 a84cbb2a 2004-04-19 devnull
237 a84cbb2a 2004-04-19 devnull static int
238 a84cbb2a 2004-04-19 devnull isstopped(int pid)
239 a84cbb2a 2004-04-19 devnull {
240 a84cbb2a 2004-04-19 devnull char buf[1024];
241 a84cbb2a 2004-04-19 devnull int fd, n;
242 a84cbb2a 2004-04-19 devnull char *p;
243 a84cbb2a 2004-04-19 devnull
244 a84cbb2a 2004-04-19 devnull snprint(buf, sizeof buf, "/proc/%d/stat", pid);
245 a84cbb2a 2004-04-19 devnull if((fd = open(buf, OREAD)) < 0)
246 a84cbb2a 2004-04-19 devnull return 0;
247 a84cbb2a 2004-04-19 devnull n = read(fd, buf, sizeof buf-1);
248 a84cbb2a 2004-04-19 devnull close(fd);
249 a84cbb2a 2004-04-19 devnull if(n <= 0)
250 a84cbb2a 2004-04-19 devnull return 0;
251 a84cbb2a 2004-04-19 devnull buf[n] = 0;
252 a84cbb2a 2004-04-19 devnull
253 a84cbb2a 2004-04-19 devnull /* command name is in parens, no parens afterward */
254 a84cbb2a 2004-04-19 devnull p = strrchr(buf, ')');
255 a84cbb2a 2004-04-19 devnull if(p == nil || *++p != ' ')
256 a84cbb2a 2004-04-19 devnull return 0;
257 a84cbb2a 2004-04-19 devnull ++p;
258 a84cbb2a 2004-04-19 devnull
259 a84cbb2a 2004-04-19 devnull /* next is state - T is stopped for tracing */
260 a84cbb2a 2004-04-19 devnull return *p == 'T';
261 a84cbb2a 2004-04-19 devnull }
262 a84cbb2a 2004-04-19 devnull
263 a84cbb2a 2004-04-19 devnull /* /proc/pid/stat contains
264 a84cbb2a 2004-04-19 devnull pid
265 a84cbb2a 2004-04-19 devnull command in parens
266 a84cbb2a 2004-04-19 devnull 0. state
267 a84cbb2a 2004-04-19 devnull 1. ppid
268 a84cbb2a 2004-04-19 devnull 2. pgrp
269 a84cbb2a 2004-04-19 devnull 3. session
270 a84cbb2a 2004-04-19 devnull 4. tty_nr
271 a84cbb2a 2004-04-19 devnull 5. tpgid
272 a84cbb2a 2004-04-19 devnull 6. flags (math=4, traced=10)
273 a84cbb2a 2004-04-19 devnull 7. minflt
274 a84cbb2a 2004-04-19 devnull 8. cminflt
275 a84cbb2a 2004-04-19 devnull 9. majflt
276 a84cbb2a 2004-04-19 devnull 10. cmajflt
277 a84cbb2a 2004-04-19 devnull 11. utime
278 a84cbb2a 2004-04-19 devnull 12. stime
279 a84cbb2a 2004-04-19 devnull 13. cutime
280 a84cbb2a 2004-04-19 devnull 14. cstime
281 a84cbb2a 2004-04-19 devnull 15. priority
282 a84cbb2a 2004-04-19 devnull 16. nice
283 a84cbb2a 2004-04-19 devnull 17. 0
284 a84cbb2a 2004-04-19 devnull 18. itrealvalue
285 a84cbb2a 2004-04-19 devnull 19. starttime
286 a84cbb2a 2004-04-19 devnull 20. vsize
287 a84cbb2a 2004-04-19 devnull 21. rss
288 a84cbb2a 2004-04-19 devnull 22. rlim
289 a84cbb2a 2004-04-19 devnull 23. startcode
290 a84cbb2a 2004-04-19 devnull 24. endcode
291 a84cbb2a 2004-04-19 devnull 25. startstack
292 a84cbb2a 2004-04-19 devnull 26. kstkesp
293 a84cbb2a 2004-04-19 devnull 27. kstkeip
294 a84cbb2a 2004-04-19 devnull 28. pending signal bitmap
295 a84cbb2a 2004-04-19 devnull 29. blocked signal bitmap
296 a84cbb2a 2004-04-19 devnull 30. ignored signal bitmap
297 a84cbb2a 2004-04-19 devnull 31. caught signal bitmap
298 a84cbb2a 2004-04-19 devnull 32. wchan
299 a84cbb2a 2004-04-19 devnull 33. nswap
300 a84cbb2a 2004-04-19 devnull 34. cnswap
301 a84cbb2a 2004-04-19 devnull 35. exit_signal
302 a84cbb2a 2004-04-19 devnull 36. processor
303 a84cbb2a 2004-04-19 devnull */
304 a84cbb2a 2004-04-19 devnull
305 a84cbb2a 2004-04-19 devnull
306 a84cbb2a 2004-04-19 devnull int
307 a84cbb2a 2004-04-19 devnull procnotes(int pid, char ***pnotes)
308 a84cbb2a 2004-04-19 devnull {
309 a84cbb2a 2004-04-19 devnull char buf[1024], *f[40];
310 a84cbb2a 2004-04-19 devnull int fd, i, n, nf;
311 a84cbb2a 2004-04-19 devnull char *p, *s, **notes;
312 a84cbb2a 2004-04-19 devnull ulong sigs;
313 a84cbb2a 2004-04-19 devnull extern char *_p9sigstr(int, char*);
314 a84cbb2a 2004-04-19 devnull
315 a84cbb2a 2004-04-19 devnull *pnotes = nil;
316 a84cbb2a 2004-04-19 devnull snprint(buf, sizeof buf, "/proc/%d/stat", pid);
317 a84cbb2a 2004-04-19 devnull if((fd = open(buf, OREAD)) < 0){
318 a84cbb2a 2004-04-19 devnull fprint(2, "open %s: %r\n", buf);
319 a84cbb2a 2004-04-19 devnull return -1;
320 a84cbb2a 2004-04-19 devnull }
321 a84cbb2a 2004-04-19 devnull n = read(fd, buf, sizeof buf-1);
322 a84cbb2a 2004-04-19 devnull close(fd);
323 a84cbb2a 2004-04-19 devnull if(n <= 0){
324 a84cbb2a 2004-04-19 devnull fprint(2, "read %s: %r\n", buf);
325 a84cbb2a 2004-04-19 devnull return -1;
326 a84cbb2a 2004-04-19 devnull }
327 a84cbb2a 2004-04-19 devnull buf[n] = 0;
328 a84cbb2a 2004-04-19 devnull
329 a84cbb2a 2004-04-19 devnull /* command name is in parens, no parens afterward */
330 a84cbb2a 2004-04-19 devnull p = strrchr(buf, ')');
331 a84cbb2a 2004-04-19 devnull if(p == nil || *++p != ' '){
332 a84cbb2a 2004-04-19 devnull fprint(2, "bad format in /proc/%d/stat\n", pid);
333 a84cbb2a 2004-04-19 devnull return -1;
334 a84cbb2a 2004-04-19 devnull }
335 a84cbb2a 2004-04-19 devnull ++p;
336 a84cbb2a 2004-04-19 devnull
337 a84cbb2a 2004-04-19 devnull nf = tokenize(p, f, nelem(f));
338 a84cbb2a 2004-04-19 devnull if(0) print("code 0x%lux-0x%lux stack 0x%lux kstk 0x%lux keip 0x%lux pending 0x%lux\n",
339 a84cbb2a 2004-04-19 devnull strtoul(f[23], 0, 0), strtoul(f[24], 0, 0), strtoul(f[25], 0, 0),
340 a84cbb2a 2004-04-19 devnull strtoul(f[26], 0, 0), strtoul(f[27], 0, 0), strtoul(f[28], 0, 0));
341 a84cbb2a 2004-04-19 devnull if(nf <= 28)
342 a84cbb2a 2004-04-19 devnull return -1;
343 a84cbb2a 2004-04-19 devnull
344 a84cbb2a 2004-04-19 devnull sigs = strtoul(f[28], 0, 0) & ~(1<<SIGCONT);
345 a84cbb2a 2004-04-19 devnull if(sigs == 0){
346 a84cbb2a 2004-04-19 devnull *pnotes = nil;
347 a84cbb2a 2004-04-19 devnull return 0;
348 a84cbb2a 2004-04-19 devnull }
349 a84cbb2a 2004-04-19 devnull
350 a84cbb2a 2004-04-19 devnull notes = mallocz(32*sizeof(char*), 0);
351 a84cbb2a 2004-04-19 devnull if(notes == nil)
352 a84cbb2a 2004-04-19 devnull return -1;
353 a84cbb2a 2004-04-19 devnull n = 0;
354 a84cbb2a 2004-04-19 devnull for(i=0; i<32; i++){
355 a84cbb2a 2004-04-19 devnull if((sigs&(1<<i)) == 0)
356 a84cbb2a 2004-04-19 devnull continue;
357 a84cbb2a 2004-04-19 devnull if((s = _p9sigstr(i, nil)) == nil)
358 a84cbb2a 2004-04-19 devnull continue;
359 a84cbb2a 2004-04-19 devnull notes[n++] = s;
360 a84cbb2a 2004-04-19 devnull }
361 a84cbb2a 2004-04-19 devnull *pnotes = notes;
362 a84cbb2a 2004-04-19 devnull return n;
363 a84cbb2a 2004-04-19 devnull }
364 a84cbb2a 2004-04-19 devnull
365 a84cbb2a 2004-04-19 devnull #undef waitpid
366 a84cbb2a 2004-04-19 devnull
367 a84cbb2a 2004-04-19 devnull int
368 a84cbb2a 2004-04-19 devnull ctlproc(int pid, char *msg)
369 a84cbb2a 2004-04-19 devnull {
370 a84cbb2a 2004-04-19 devnull int p, status;
371 a84cbb2a 2004-04-19 devnull
372 a84cbb2a 2004-04-19 devnull if(strcmp(msg, "hang") == 0){
373 a84cbb2a 2004-04-19 devnull if(pid == getpid())
374 a84cbb2a 2004-04-19 devnull return ptrace(PTRACE_TRACEME, 0, 0, 0);
375 a84cbb2a 2004-04-19 devnull werrstr("can only hang self");
376 a84cbb2a 2004-04-19 devnull return -1;
377 a84cbb2a 2004-04-19 devnull }
378 a84cbb2a 2004-04-19 devnull if(strcmp(msg, "kill") == 0)
379 a84cbb2a 2004-04-19 devnull return ptrace(PTRACE_KILL, pid, 0, 0);
380 a84cbb2a 2004-04-19 devnull if(strcmp(msg, "startstop") == 0){
381 a84cbb2a 2004-04-19 devnull if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
382 a84cbb2a 2004-04-19 devnull return -1;
383 a84cbb2a 2004-04-19 devnull goto waitstop;
384 a84cbb2a 2004-04-19 devnull }
385 a84cbb2a 2004-04-19 devnull if(strcmp(msg, "sysstop") == 0){
386 a84cbb2a 2004-04-19 devnull if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
387 a84cbb2a 2004-04-19 devnull return -1;
388 a84cbb2a 2004-04-19 devnull goto waitstop;
389 a84cbb2a 2004-04-19 devnull }
390 a84cbb2a 2004-04-19 devnull if(strcmp(msg, "stop") == 0){
391 a84cbb2a 2004-04-19 devnull if(kill(pid, SIGSTOP) < 0)
392 a84cbb2a 2004-04-19 devnull return -1;
393 a84cbb2a 2004-04-19 devnull goto waitstop;
394 a84cbb2a 2004-04-19 devnull }
395 a84cbb2a 2004-04-19 devnull if(strcmp(msg, "waitstop") == 0){
396 a84cbb2a 2004-04-19 devnull waitstop:
397 a84cbb2a 2004-04-19 devnull if(isstopped(pid))
398 a84cbb2a 2004-04-19 devnull return 0;
399 a84cbb2a 2004-04-19 devnull for(;;){
400 2e965b33 2004-05-05 devnull p = waitpid(pid, &status, WUNTRACED|__WALL);
401 2e965b33 2004-05-05 devnull if(p <= 0){
402 2e965b33 2004-05-05 devnull if(errno == ECHILD){
403 2e965b33 2004-05-05 devnull if(isstopped(pid))
404 2e965b33 2004-05-05 devnull return 0;
405 2e965b33 2004-05-05 devnull }
406 a84cbb2a 2004-04-19 devnull return -1;
407 2e965b33 2004-05-05 devnull }
408 a84cbb2a 2004-04-19 devnull if(WIFEXITED(status) || WIFSTOPPED(status))
409 a84cbb2a 2004-04-19 devnull return 0;
410 a84cbb2a 2004-04-19 devnull }
411 a84cbb2a 2004-04-19 devnull }
412 a84cbb2a 2004-04-19 devnull if(strcmp(msg, "start") == 0)
413 a84cbb2a 2004-04-19 devnull return ptrace(PTRACE_CONT, pid, 0, 0);
414 a84cbb2a 2004-04-19 devnull werrstr("unknown control message '%s'", msg);
415 a84cbb2a 2004-04-19 devnull return -1;
416 a84cbb2a 2004-04-19 devnull }
417 a84cbb2a 2004-04-19 devnull
418 a84cbb2a 2004-04-19 devnull char*
419 a84cbb2a 2004-04-19 devnull proctextfile(int pid)
420 a84cbb2a 2004-04-19 devnull {
421 a84cbb2a 2004-04-19 devnull static char buf[1024], pbuf[128];
422 a84cbb2a 2004-04-19 devnull
423 a84cbb2a 2004-04-19 devnull snprint(pbuf, sizeof pbuf, "/proc/%d/exe", pid);
424 a84cbb2a 2004-04-19 devnull if(readlink(pbuf, buf, sizeof buf) >= 0)
425 a84cbb2a 2004-04-19 devnull return buf;
426 a84cbb2a 2004-04-19 devnull if(access(pbuf, AEXIST) >= 0)
427 a84cbb2a 2004-04-19 devnull return pbuf;
428 a84cbb2a 2004-04-19 devnull return nil;
429 a84cbb2a 2004-04-19 devnull }
430 a84cbb2a 2004-04-19 devnull
431 a84cbb2a 2004-04-19 devnull
432 a84cbb2a 2004-04-19 devnull #if 0
433 a84cbb2a 2004-04-19 devnull snprint(buf, sizeof buf, "/proc/%d/maps", pid);
434 a84cbb2a 2004-04-19 devnull if((b = Bopen(buf, OREAD)) == nil){
435 a84cbb2a 2004-04-19 devnull werrstr("open %s: %r", buf);
436 a84cbb2a 2004-04-19 devnull return -1;
437 a84cbb2a 2004-04-19 devnull }
438 a84cbb2a 2004-04-19 devnull
439 a84cbb2a 2004-04-19 devnull /*
440 a84cbb2a 2004-04-19 devnull 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm
441 a84cbb2a 2004-04-19 devnull 08056000-08058000 rw-p 0000d000 03:0c 64593 /usr/sbin/gpm
442 a84cbb2a 2004-04-19 devnull 08058000-0805b000 rwxp 00000000 00:00 0
443 a84cbb2a 2004-04-19 devnull 40000000-40013000 r-xp 00000000 03:0c 4165 /lib/ld-2.2.4.so
444 a84cbb2a 2004-04-19 devnull 40013000-40015000 rw-p 00012000 03:0c 4165 /lib/ld-2.2.4.so
445 a84cbb2a 2004-04-19 devnull 4001f000-40135000 r-xp 00000000 03:0c 45494 /lib/libc-2.2.4.so
446 a84cbb2a 2004-04-19 devnull 40135000-4013e000 rw-p 00115000 03:0c 45494 /lib/libc-2.2.4.so
447 a84cbb2a 2004-04-19 devnull 4013e000-40142000 rw-p 00000000 00:00 0
448 a84cbb2a 2004-04-19 devnull bffff000-c0000000 rwxp 00000000 00:00 0
449 a84cbb2a 2004-04-19 devnull */
450 a84cbb2a 2004-04-19 devnull
451 a84cbb2a 2004-04-19 devnull file = nil;
452 a84cbb2a 2004-04-19 devnull while((p = Brdline(b, '\n')) != nil){
453 a84cbb2a 2004-04-19 devnull p[Blinelen(b)-1] = 0;
454 a84cbb2a 2004-04-19 devnull memset(f, 0, sizeof f);
455 a84cbb2a 2004-04-19 devnull if((nf = getfields(p, f, 6, 1, " ")) < 5)
456 a84cbb2a 2004-04-19 devnull continue;
457 a84cbb2a 2004-04-19 devnull base = strtoul(f[0], &p, 16);
458 a84cbb2a 2004-04-19 devnull if(*p != '-')
459 a84cbb2a 2004-04-19 devnull continue;
460 a84cbb2a 2004-04-19 devnull end = strtoul(p+1, &p, 16);
461 a84cbb2a 2004-04-19 devnull if(*p != 0)
462 a84cbb2a 2004-04-19 devnull continue;
463 a84cbb2a 2004-04-19 devnull offset = strtoul(f[2], &p, 16);
464 a84cbb2a 2004-04-19 devnull if(*p != 0)
465 a84cbb2a 2004-04-19 devnull continue;
466 a84cbb2a 2004-04-19 devnull if(nf == 6)
467 a84cbb2a 2004-04-19 devnull file = f[5];
468 a84cbb2a 2004-04-19 devnull zero = atoi(f[4]) == 0;
469 a84cbb2a 2004-04-19 devnull print("%lux-%lux %lux %s %s\n", base, end, offset, zero ? "data" : "text", file ? file : "");
470 a84cbb2a 2004-04-19 devnull s.base = base;
471 a84cbb2a 2004-04-19 devnull s.size = end - base;
472 a84cbb2a 2004-04-19 devnull s.offset = offset;
473 a84cbb2a 2004-04-19 devnull s.name = zero ? "data" : "text";
474 a84cbb2a 2004-04-19 devnull s.file = strdup(file);
475 a84cbb2a 2004-04-19 devnull s.rw = ptracerw;
476 a84cbb2a 2004-04-19 devnull s.pid = pid;
477 a84cbb2a 2004-04-19 devnull if(addseg(map, s) < 0){
478 a84cbb2a 2004-04-19 devnull Bterm(b);
479 a84cbb2a 2004-04-19 devnull ptrace(PTRACE_DETACH, pid, 0, 0);
480 a84cbb2a 2004-04-19 devnull return -1;
481 a84cbb2a 2004-04-19 devnull }
482 a84cbb2a 2004-04-19 devnull }
483 a84cbb2a 2004-04-19 devnull Bterm(b);
484 a84cbb2a 2004-04-19 devnull #endif
485 a84cbb2a 2004-04-19 devnull