1 /* Get Dwarf Frame state for target live PID process.
2 Copyright (C) 2013, 2014, 2015 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
7
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
11
12 or
13
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
17
18 or both in parallel, as here.
19
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
28
29 #include "libelfP.h"
30 #include "libdwflP.h"
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <sys/ptrace.h>
35 #include <sys/wait.h>
36 #include <dirent.h>
37 #include <sys/syscall.h>
38 #include <unistd.h>
39
40 #ifndef MAX
41 # define MAX(a, b) ((a) > (b) ? (a) : (b))
42 #endif
43
44 #ifdef __linux__
45
46 static bool
linux_proc_pid_is_stopped(pid_t pid)47 linux_proc_pid_is_stopped (pid_t pid)
48 {
49 char buffer[64];
50 FILE *procfile;
51 bool retval, have_state;
52
53 snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
54 procfile = fopen (buffer, "r");
55 if (procfile == NULL)
56 return false;
57
58 have_state = false;
59 while (fgets (buffer, sizeof (buffer), procfile) != NULL)
60 if (strncmp (buffer, "State:", 6) == 0)
61 {
62 have_state = true;
63 break;
64 }
65 retval = (have_state && strstr (buffer, "T (stopped)") != NULL);
66 fclose (procfile);
67 return retval;
68 }
69
70 bool
71 internal_function
__libdwfl_ptrace_attach(pid_t tid,bool * tid_was_stoppedp)72 __libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
73 {
74 if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
75 {
76 __libdwfl_seterrno (DWFL_E_ERRNO);
77 return false;
78 }
79 *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
80 if (*tid_was_stoppedp)
81 {
82 /* Make sure there is a SIGSTOP signal pending even when the process is
83 already State: T (stopped). Older kernels might fail to generate
84 a SIGSTOP notification in that case in response to our PTRACE_ATTACH
85 above. Which would make the waitpid below wait forever. So emulate
86 it. Since there can only be one SIGSTOP notification pending this is
87 safe. See also gdb/linux-nat.c linux_nat_post_attach_wait. */
88 syscall (__NR_tkill, tid, SIGSTOP);
89 ptrace (PTRACE_CONT, tid, NULL, NULL);
90 }
91 for (;;)
92 {
93 int status;
94 if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status))
95 {
96 int saved_errno = errno;
97 ptrace (PTRACE_DETACH, tid, NULL, NULL);
98 errno = saved_errno;
99 __libdwfl_seterrno (DWFL_E_ERRNO);
100 return false;
101 }
102 if (WSTOPSIG (status) == SIGSTOP)
103 break;
104 if (ptrace (PTRACE_CONT, tid, NULL,
105 (void *) (uintptr_t) WSTOPSIG (status)) != 0)
106 {
107 int saved_errno = errno;
108 ptrace (PTRACE_DETACH, tid, NULL, NULL);
109 errno = saved_errno;
110 __libdwfl_seterrno (DWFL_E_ERRNO);
111 return false;
112 }
113 }
114 return true;
115 }
116
117 static bool
pid_memory_read(Dwfl * dwfl,Dwarf_Addr addr,Dwarf_Word * result,void * arg)118 pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
119 {
120 struct __libdwfl_pid_arg *pid_arg = arg;
121 pid_t tid = pid_arg->tid_attached;
122 assert (tid > 0);
123 Dwfl_Process *process = dwfl->process;
124 if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
125 {
126 #if SIZEOF_LONG == 8
127 errno = 0;
128 *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
129 return errno == 0;
130 #else /* SIZEOF_LONG != 8 */
131 /* This should not happen. */
132 return false;
133 #endif /* SIZEOF_LONG != 8 */
134 }
135 #if SIZEOF_LONG == 8
136 /* We do not care about reads unaliged to 4 bytes boundary.
137 But 0x...ffc read of 8 bytes could overrun a page. */
138 bool lowered = (addr & 4) != 0;
139 if (lowered)
140 addr -= 4;
141 #endif /* SIZEOF_LONG == 8 */
142 errno = 0;
143 *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
144 if (errno != 0)
145 return false;
146 #if SIZEOF_LONG == 8
147 # if BYTE_ORDER == BIG_ENDIAN
148 if (! lowered)
149 *result >>= 32;
150 # else
151 if (lowered)
152 *result >>= 32;
153 # endif
154 #endif /* SIZEOF_LONG == 8 */
155 *result &= 0xffffffff;
156 return true;
157 }
158
159 static pid_t
pid_next_thread(Dwfl * dwfl,void * dwfl_arg,void ** thread_argp)160 pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
161 void **thread_argp)
162 {
163 struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
164 struct dirent *dirent;
165 /* Start fresh on first traversal. */
166 if (*thread_argp == NULL)
167 rewinddir (pid_arg->dir);
168 do
169 {
170 errno = 0;
171 dirent = readdir (pid_arg->dir);
172 if (dirent == NULL)
173 {
174 if (errno != 0)
175 {
176 __libdwfl_seterrno (DWFL_E_ERRNO);
177 return -1;
178 }
179 return 0;
180 }
181 }
182 while (strcmp (dirent->d_name, ".") == 0
183 || strcmp (dirent->d_name, "..") == 0);
184 char *end;
185 errno = 0;
186 long tidl = strtol (dirent->d_name, &end, 10);
187 if (errno != 0)
188 {
189 __libdwfl_seterrno (DWFL_E_ERRNO);
190 return -1;
191 }
192 pid_t tid = tidl;
193 if (tidl <= 0 || (end && *end) || tid != tidl)
194 {
195 __libdwfl_seterrno (DWFL_E_PARSE_PROC);
196 return -1;
197 }
198 *thread_argp = dwfl_arg;
199 return tid;
200 }
201
202 /* Just checks that the thread id exists. */
203 static bool
pid_getthread(Dwfl * dwfl,pid_t tid,void * dwfl_arg,void ** thread_argp)204 pid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid,
205 void *dwfl_arg, void **thread_argp)
206 {
207 *thread_argp = dwfl_arg;
208 if (kill (tid, 0) < 0)
209 {
210 __libdwfl_seterrno (DWFL_E_ERRNO);
211 return false;
212 }
213 return true;
214 }
215
216 /* Implement the ebl_set_initial_registers_tid setfunc callback. */
217
218 static bool
pid_thread_state_registers_cb(int firstreg,unsigned nregs,const Dwarf_Word * regs,void * arg)219 pid_thread_state_registers_cb (int firstreg, unsigned nregs,
220 const Dwarf_Word *regs, void *arg)
221 {
222 Dwfl_Thread *thread = (Dwfl_Thread *) arg;
223 if (firstreg < 0)
224 {
225 assert (firstreg == -1);
226 assert (nregs == 1);
227 INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
228 return true;
229 }
230 assert (nregs > 0);
231 return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
232 }
233
234 static bool
pid_set_initial_registers(Dwfl_Thread * thread,void * thread_arg)235 pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
236 {
237 struct __libdwfl_pid_arg *pid_arg = thread_arg;
238 assert (pid_arg->tid_attached == 0);
239 pid_t tid = INTUSE(dwfl_thread_tid) (thread);
240 if (! pid_arg->assume_ptrace_stopped
241 && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
242 return false;
243 pid_arg->tid_attached = tid;
244 Dwfl_Process *process = thread->process;
245 Ebl *ebl = process->ebl;
246 return ebl_set_initial_registers_tid (ebl, tid,
247 pid_thread_state_registers_cb, thread);
248 }
249
250 static void
pid_detach(Dwfl * dwfl,void * dwfl_arg)251 pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
252 {
253 struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
254 elf_end (pid_arg->elf);
255 close (pid_arg->elf_fd);
256 closedir (pid_arg->dir);
257 free (pid_arg);
258 }
259
260 void
261 internal_function
__libdwfl_ptrace_detach(pid_t tid,bool tid_was_stopped)262 __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
263 {
264 /* This handling is needed only on older Linux kernels such as
265 2.6.32-358.23.2.el6.ppc64. Later kernels such as
266 3.11.7-200.fc19.x86_64 remember the T (stopped) state
267 themselves and no longer need to pass SIGSTOP during
268 PTRACE_DETACH. */
269 ptrace (PTRACE_DETACH, tid, NULL,
270 (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
271 }
272
273 static void
pid_thread_detach(Dwfl_Thread * thread,void * thread_arg)274 pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
275 {
276 struct __libdwfl_pid_arg *pid_arg = thread_arg;
277 pid_t tid = INTUSE(dwfl_thread_tid) (thread);
278 assert (pid_arg->tid_attached == tid);
279 pid_arg->tid_attached = 0;
280 if (! pid_arg->assume_ptrace_stopped)
281 __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
282 }
283
284 static const Dwfl_Thread_Callbacks pid_thread_callbacks =
285 {
286 pid_next_thread,
287 pid_getthread,
288 pid_memory_read,
289 pid_set_initial_registers,
290 pid_detach,
291 pid_thread_detach,
292 };
293
294 int
dwfl_linux_proc_attach(Dwfl * dwfl,pid_t pid,bool assume_ptrace_stopped)295 dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
296 {
297 char buffer[36];
298 FILE *procfile;
299 int err = 0; /* The errno to return and set for dwfl->attcherr. */
300
301 /* Make sure to report the actual PID (thread group leader) to
302 dwfl_attach_state. */
303 snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
304 procfile = fopen (buffer, "r");
305 if (procfile == NULL)
306 {
307 err = errno;
308 fail:
309 if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
310 {
311 errno = err;
312 dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
313 }
314 return err;
315 }
316
317 char *line = NULL;
318 size_t linelen = 0;
319 while (getline (&line, &linelen, procfile) >= 0)
320 if (strncmp (line, "Tgid:", 5) == 0)
321 {
322 errno = 0;
323 char *endptr;
324 long val = strtol (&line[5], &endptr, 10);
325 if ((errno == ERANGE && val == LONG_MAX)
326 || *endptr != '\n' || val < 0 || val != (pid_t) val)
327 pid = 0;
328 else
329 pid = (pid_t) val;
330 break;
331 }
332 free (line);
333 fclose (procfile);
334
335 if (pid == 0)
336 {
337 err = ESRCH;
338 goto fail;
339 }
340
341 char name[64];
342 int i = snprintf (name, sizeof (name), "/proc/%ld/task", (long) pid);
343 assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
344 DIR *dir = opendir (name);
345 if (dir == NULL)
346 {
347 err = errno;
348 goto fail;
349 }
350
351 Elf *elf;
352 i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid);
353 assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
354 int elf_fd = open (name, O_RDONLY);
355 if (elf_fd >= 0)
356 {
357 elf = elf_begin (elf_fd, ELF_C_READ_MMAP, NULL);
358 if (elf == NULL)
359 {
360 /* Just ignore, dwfl_attach_state will fall back to trying
361 to associate the Dwfl with one of the existing DWfl_Module
362 ELF images (to know the machine/class backend to use). */
363 close (elf_fd);
364 elf_fd = -1;
365 }
366 }
367 else
368 elf = NULL;
369 struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
370 if (pid_arg == NULL)
371 {
372 elf_end (elf);
373 close (elf_fd);
374 closedir (dir);
375 err = ENOMEM;
376 goto fail;
377 }
378 pid_arg->dir = dir;
379 pid_arg->elf = elf;
380 pid_arg->elf_fd = elf_fd;
381 pid_arg->tid_attached = 0;
382 pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
383 if (! INTUSE(dwfl_attach_state) (dwfl, elf, pid, &pid_thread_callbacks,
384 pid_arg))
385 {
386 elf_end (elf);
387 close (elf_fd);
388 closedir (dir);
389 free (pid_arg);
390 return -1;
391 }
392 return 0;
393 }
INTDEF(dwfl_linux_proc_attach)394 INTDEF (dwfl_linux_proc_attach)
395
396 struct __libdwfl_pid_arg *
397 internal_function
398 __libdwfl_get_pid_arg (Dwfl *dwfl)
399 {
400 if (dwfl != NULL && dwfl->process != NULL
401 && dwfl->process->callbacks == &pid_thread_callbacks)
402 return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;
403
404 return NULL;
405 }
406
407 #else /* __linux__ */
408
409 static pid_t
pid_next_thread(Dwfl * dwfl,void * dwfl_arg,void ** thread_argp)410 pid_next_thread (Dwfl *dwfl __attribute__ ((unused)),
411 void *dwfl_arg __attribute__ ((unused)),
412 void **thread_argp __attribute__ ((unused)))
413 {
414 errno = ENOSYS;
415 __libdwfl_seterrno (DWFL_E_ERRNO);
416 return -1;
417 }
418
419 static bool
pid_getthread(Dwfl * dwfl,pid_t tid,void * dwfl_arg,void ** thread_argp)420 pid_getthread (Dwfl *dwfl __attribute__ ((unused)),
421 pid_t tid __attribute__ ((unused)),
422 void *dwfl_arg __attribute__ ((unused)),
423 void **thread_argp __attribute__ ((unused)))
424 {
425 errno = ENOSYS;
426 __libdwfl_seterrno (DWFL_E_ERRNO);
427 return false;
428 }
429
430 bool
431 internal_function
__libdwfl_ptrace_attach(pid_t tid,bool * tid_was_stoppedp)432 __libdwfl_ptrace_attach (pid_t tid __attribute__ ((unused)),
433 bool *tid_was_stoppedp __attribute__ ((unused)))
434 {
435 errno = ENOSYS;
436 __libdwfl_seterrno (DWFL_E_ERRNO);
437 return false;
438 }
439
440 static bool
pid_memory_read(Dwfl * dwfl,Dwarf_Addr addr,Dwarf_Word * result,void * arg)441 pid_memory_read (Dwfl *dwfl __attribute__ ((unused)),
442 Dwarf_Addr addr __attribute__ ((unused)),
443 Dwarf_Word *result __attribute__ ((unused)),
444 void *arg __attribute__ ((unused)))
445 {
446 errno = ENOSYS;
447 __libdwfl_seterrno (DWFL_E_ERRNO);
448 return false;
449 }
450
451 static bool
pid_set_initial_registers(Dwfl_Thread * thread,void * thread_arg)452 pid_set_initial_registers (Dwfl_Thread *thread __attribute__ ((unused)),
453 void *thread_arg __attribute__ ((unused)))
454 {
455 errno = ENOSYS;
456 __libdwfl_seterrno (DWFL_E_ERRNO);
457 return false;
458 }
459
460 static void
pid_detach(Dwfl * dwfl,void * dwfl_arg)461 pid_detach (Dwfl *dwfl __attribute__ ((unused)),
462 void *dwfl_arg __attribute__ ((unused)))
463 {
464 }
465
466 void
467 internal_function
__libdwfl_ptrace_detach(pid_t tid,bool tid_was_stopped)468 __libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
469 bool tid_was_stopped __attribute__ ((unused)))
470 {
471 }
472
473 static void
pid_thread_detach(Dwfl_Thread * thread,void * thread_arg)474 pid_thread_detach (Dwfl_Thread *thread __attribute__ ((unused)),
475 void *thread_arg __attribute__ ((unused)))
476 {
477 }
478
479 static const Dwfl_Thread_Callbacks pid_thread_callbacks =
480 {
481 pid_next_thread,
482 pid_getthread,
483 pid_memory_read,
484 pid_set_initial_registers,
485 pid_detach,
486 pid_thread_detach,
487 };
488
489 int
dwfl_linux_proc_attach(Dwfl * dwfl,pid_t pid,bool assume_ptrace_stopped)490 dwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
491 pid_t pid __attribute__ ((unused)),
492 bool assume_ptrace_stopped __attribute__ ((unused)))
493 {
494 return ENOSYS;
495 }
INTDEF(dwfl_linux_proc_attach)496 INTDEF (dwfl_linux_proc_attach)
497
498 struct __libdwfl_pid_arg *
499 internal_function
500 __libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
501 {
502 return NULL;
503 }
504
505 #endif /* ! __linux __ */
506
507