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