Blame


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