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