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 : 128 : 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 [ - + ]: 128 : 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 : 128 : struct __libdwfl_remote_mem_cache *mem_cache = pid_arg->mem_cache;
134 [ + + ]: 128 : if (mem_cache == NULL)
135 : : {
136 : 6 : size_t mem_cache_size = sizeof (struct __libdwfl_remote_mem_cache);
137 : 6 : mem_cache = malloc (mem_cache_size);
138 [ - + ]: 6 : if (mem_cache == NULL)
139 : : return false;
140 : :
141 : 6 : mem_cache->addr = 0;
142 : 6 : mem_cache->len = 0;
143 : 6 : pid_arg->mem_cache = mem_cache;
144 : : }
145 : :
146 : 128 : unsigned char *d;
147 [ + + + + ]: 128 : if (addr >= mem_cache->addr && addr - mem_cache->addr < mem_cache->len)
148 : : {
149 : 118 : d = &mem_cache->buf[addr - mem_cache->addr];
150 [ + - ]: 118 : if ((((uintptr_t) d) & (sizeof (unsigned long) - 1)) == 0)
151 : 118 : *result = *(unsigned long *) d;
152 : : else
153 : 0 : memcpy (result, d, sizeof (unsigned long));
154 : 118 : return true;
155 : : }
156 : :
157 : 10 : struct iovec local, remote;
158 : 10 : mem_cache->addr = addr & ~((Dwarf_Addr)__LIBDWFL_REMOTE_MEM_CACHE_SIZE - 1);
159 : 10 : local.iov_base = mem_cache->buf;
160 : 10 : local.iov_len = __LIBDWFL_REMOTE_MEM_CACHE_SIZE;
161 : 10 : remote.iov_base = (void *) (uintptr_t) mem_cache->addr;
162 : 10 : remote.iov_len = __LIBDWFL_REMOTE_MEM_CACHE_SIZE;
163 : :
164 : 10 : ssize_t res = process_vm_readv (pid_arg->tid_attached,
165 : : &local, 1, &remote, 1, 0);
166 [ - + ]: 10 : if (res != __LIBDWFL_REMOTE_MEM_CACHE_SIZE)
167 : : {
168 : 0 : mem_cache->len = 0;
169 : 0 : return false;
170 : : }
171 : :
172 : 10 : mem_cache->len = res;
173 : 10 : d = &mem_cache->buf[addr - mem_cache->addr];
174 [ + - ]: 10 : if ((((uintptr_t) d) & (sizeof (unsigned long) - 1)) == 0)
175 : 10 : *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 : 6 : clear_cached_memory (struct __libdwfl_pid_arg *pid_arg)
184 : : {
185 : 6 : struct __libdwfl_remote_mem_cache *mem_cache = pid_arg->mem_cache;
186 : 6 : if (mem_cache != NULL)
187 : 6 : 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 : 128 : pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
194 : : {
195 : 128 : struct __libdwfl_pid_arg *pid_arg = arg;
196 : 128 : pid_t tid = pid_arg->tid_attached;
197 : 128 : Dwfl_Process *process = dwfl->process;
198 [ - + ]: 128 : assert (tid > 0);
199 : :
200 : : #ifdef HAVE_PROCESS_VM_READV
201 [ + - ]: 128 : 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 [ # # ]: 0 : 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 : 0 : bool lowered = (addr & 4) != 0;
228 [ # # ]: 0 : if (lowered)
229 : 0 : addr -= 4;
230 : : #endif /* SIZEOF_LONG == 8 */
231 : 0 : errno = 0;
232 : 0 : *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
233 [ # # ]: 0 : 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 [ # # ]: 0 : if (lowered)
241 : 0 : *result >>= 32;
242 : : # endif
243 : : #endif /* SIZEOF_LONG == 8 */
244 : 0 : *result &= 0xffffffff;
245 : 0 : return true;
246 : : }
247 : :
248 : : static pid_t
249 : 20 : pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
250 : : void **thread_argp)
251 : : {
252 : 20 : struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
253 : 20 : struct dirent *dirent;
254 : : /* Start fresh on first traversal. */
255 [ + + ]: 20 : if (*thread_argp == NULL)
256 : 8 : rewinddir (pid_arg->dir);
257 : 36 : do
258 : : {
259 : 36 : errno = 0;
260 : 36 : dirent = readdir (pid_arg->dir);
261 [ + + ]: 36 : if (dirent == NULL)
262 : : {
263 [ - + ]: 6 : if (errno != 0)
264 : : {
265 : 0 : __libdwfl_seterrno (DWFL_E_ERRNO);
266 : 0 : return -1;
267 : : }
268 : : return 0;
269 : : }
270 : : }
271 : 30 : while (strcmp (dirent->d_name, ".") == 0
272 [ + + + + ]: 30 : || strcmp (dirent->d_name, "..") == 0);
273 : 14 : char *end;
274 : 14 : errno = 0;
275 : 14 : long tidl = strtol (dirent->d_name, &end, 10);
276 [ - + ]: 14 : if (errno != 0)
277 : : {
278 : 0 : __libdwfl_seterrno (DWFL_E_ERRNO);
279 : 0 : return -1;
280 : : }
281 : 14 : pid_t tid = tidl;
282 [ + - + - : 14 : if (tidl <= 0 || (end && *end) || tid != tidl)
+ - - + ]
283 : : {
284 : 0 : __libdwfl_seterrno (DWFL_E_PARSE_PROC);
285 : 0 : return -1;
286 : : }
287 : 14 : *thread_argp = dwfl_arg;
288 : 14 : 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 : 8 : pid_thread_state_registers_cb (int firstreg, unsigned nregs,
309 : : const Dwarf_Word *regs, void *arg)
310 : : {
311 : 8 : Dwfl_Thread *thread = (Dwfl_Thread *) arg;
312 [ - + ]: 8 : if (firstreg == -1)
313 : : {
314 [ # # ]: 0 : assert (nregs == 1);
315 : 0 : INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
316 : 0 : return true;
317 : : }
318 [ - + ]: 8 : else if (firstreg == -2)
319 : : {
320 [ # # ]: 0 : assert (nregs == 1);
321 : 0 : INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
322 : 0 : return true;
323 : : }
324 [ - + ]: 8 : assert (nregs > 0);
325 : 8 : return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
326 : : }
327 : :
328 : : static bool
329 : 8 : pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
330 : : {
331 : 8 : struct __libdwfl_pid_arg *pid_arg = thread_arg;
332 [ - + ]: 8 : assert (pid_arg->tid_attached == 0);
333 : 8 : pid_t tid = INTUSE(dwfl_thread_tid) (thread);
334 [ + + ]: 8 : if (! pid_arg->assume_ptrace_stopped
335 [ + - ]: 2 : && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
336 : : return false;
337 : 8 : pid_arg->tid_attached = tid;
338 : 8 : Dwfl_Process *process = thread->process;
339 : 8 : Ebl *ebl = process->ebl;
340 : 8 : return ebl_set_initial_registers_tid (ebl, tid,
341 : : pid_thread_state_registers_cb, thread);
342 : : }
343 : :
344 : : static void
345 : 26 : pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
346 : : {
347 : 26 : struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
348 : 26 : elf_end (pid_arg->elf);
349 : 26 : free (pid_arg->mem_cache);
350 : 26 : close (pid_arg->elf_fd);
351 : 26 : closedir (pid_arg->dir);
352 : 26 : free (pid_arg);
353 : 26 : }
354 : :
355 : : void
356 : : internal_function
357 : 14 : __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
358 : : {
359 : : /* This handling is needed only on older Linux kernels such as
360 : : 2.6.32-358.23.2.el6.ppc64. Later kernels such as
361 : : 3.11.7-200.fc19.x86_64 remember the T (stopped) state
362 : : themselves and no longer need to pass SIGSTOP during
363 : : PTRACE_DETACH. */
364 [ + - ]: 28 : ptrace (PTRACE_DETACH, tid, NULL,
365 : : (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
366 : 14 : }
367 : :
368 : : static void
369 : 6 : pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
370 : : {
371 : 6 : struct __libdwfl_pid_arg *pid_arg = thread_arg;
372 : 6 : pid_t tid = INTUSE(dwfl_thread_tid) (thread);
373 [ - + ]: 6 : assert (pid_arg->tid_attached == tid);
374 : 6 : pid_arg->tid_attached = 0;
375 [ + - ]: 6 : clear_cached_memory (pid_arg);
376 [ + + ]: 6 : if (! pid_arg->assume_ptrace_stopped)
377 : 2 : __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
378 : 6 : }
379 : :
380 : : static const Dwfl_Thread_Callbacks pid_thread_callbacks =
381 : : {
382 : : pid_next_thread,
383 : : pid_getthread,
384 : : pid_memory_read,
385 : : pid_set_initial_registers,
386 : : pid_detach,
387 : : pid_thread_detach,
388 : : };
389 : :
390 : : int
391 : 28 : dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
392 : : {
393 : 28 : char buffer[36];
394 : 28 : FILE *procfile;
395 : 28 : int err = 0; /* The errno to return and set for dwfl->attcherr. */
396 : :
397 : : /* Make sure to report the actual PID (thread group leader) to
398 : : dwfl_attach_state. */
399 : 28 : snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
400 : 28 : procfile = fopen (buffer, "r");
401 [ - + ]: 28 : if (procfile == NULL)
402 : : {
403 : 0 : err = errno;
404 : 0 : fail:
405 [ # # # # ]: 0 : if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
406 : : {
407 : 0 : errno = err;
408 : 0 : dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
409 : : }
410 : 0 : return err;
411 : : }
412 : :
413 : 28 : char *line = NULL;
414 : 28 : size_t linelen = 0;
415 [ + - ]: 112 : while (getline (&line, &linelen, procfile) >= 0)
416 [ + + ]: 112 : if (startswith (line, "Tgid:"))
417 : : {
418 : 28 : errno = 0;
419 : 28 : char *endptr;
420 : 28 : long val = strtol (&line[5], &endptr, 10);
421 [ - + - - ]: 28 : if ((errno == ERANGE && val == LONG_MAX)
422 [ - + - + : 28 : || *endptr != '\n' || val < 0 || val != (pid_t) val)
- + ]
423 : : pid = 0;
424 : : else
425 : 28 : pid = (pid_t) val;
426 : 28 : break;
427 : : }
428 : 28 : free (line);
429 : 28 : fclose (procfile);
430 : :
431 [ - + ]: 28 : if (pid == 0)
432 : : {
433 : 0 : err = ESRCH;
434 : 0 : goto fail;
435 : : }
436 : :
437 : 28 : char name[64];
438 [ - + ]: 28 : int i = snprintf (name, sizeof (name), "/proc/%ld/task", (long) pid);
439 [ - + ]: 28 : if (i <= 0 || i >= (ssize_t) sizeof (name) - 1)
440 : : {
441 : 0 : errno = -ENOMEM;
442 : 0 : goto fail;
443 : : }
444 : 28 : DIR *dir = opendir (name);
445 [ - + ]: 28 : if (dir == NULL)
446 : : {
447 : 0 : err = errno;
448 : 0 : goto fail;
449 : : }
450 : :
451 : 28 : Elf *elf;
452 [ - + ]: 28 : i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid);
453 [ - + ]: 28 : assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
454 : 28 : int elf_fd = open (name, O_RDONLY);
455 [ + - ]: 28 : if (elf_fd >= 0)
456 : : {
457 : 28 : elf = elf_begin (elf_fd, ELF_C_READ_MMAP, NULL);
458 [ - + ]: 28 : if (elf == NULL)
459 : : {
460 : : /* Just ignore, dwfl_attach_state will fall back to trying
461 : : to associate the Dwfl with one of the existing DWfl_Module
462 : : ELF images (to know the machine/class backend to use). */
463 : 0 : close (elf_fd);
464 : 0 : elf_fd = -1;
465 : : }
466 : : }
467 : : else
468 : : elf = NULL;
469 : 28 : struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
470 [ - + ]: 28 : if (pid_arg == NULL)
471 : : {
472 : 0 : elf_end (elf);
473 : 0 : close (elf_fd);
474 : 0 : closedir (dir);
475 : 0 : err = ENOMEM;
476 : 0 : goto fail;
477 : : }
478 : 28 : pid_arg->dir = dir;
479 : 28 : pid_arg->elf = elf;
480 : 28 : pid_arg->elf_fd = elf_fd;
481 : 28 : pid_arg->mem_cache = NULL;
482 : 28 : pid_arg->tid_attached = 0;
483 : 28 : pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
484 [ - + ]: 28 : if (! INTUSE(dwfl_attach_state) (dwfl, elf, pid, &pid_thread_callbacks,
485 : : pid_arg))
486 : : {
487 : 0 : elf_end (elf);
488 : 0 : close (elf_fd);
489 : 0 : closedir (dir);
490 : 0 : free (pid_arg);
491 : 0 : return -1;
492 : : }
493 : : return 0;
494 : : }
495 : : INTDEF (dwfl_linux_proc_attach)
496 : :
497 : : struct __libdwfl_pid_arg *
498 : : internal_function
499 : 16 : __libdwfl_get_pid_arg (Dwfl *dwfl)
500 : : {
501 [ + - + - ]: 16 : if (dwfl != NULL && dwfl->process != NULL
502 [ + - ]: 16 : && dwfl->process->callbacks == &pid_thread_callbacks)
503 : 16 : return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;
504 : :
505 : : return NULL;
506 : : }
507 : :
508 : : #else /* __linux__ */
509 : :
510 : : bool
511 : : internal_function
512 : : __libdwfl_ptrace_attach (pid_t tid __attribute__ ((unused)),
513 : : bool *tid_was_stoppedp __attribute__ ((unused)))
514 : : {
515 : : errno = ENOSYS;
516 : : __libdwfl_seterrno (DWFL_E_ERRNO);
517 : : return false;
518 : : }
519 : :
520 : : void
521 : : internal_function
522 : : __libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
523 : : bool tid_was_stopped __attribute__ ((unused)))
524 : : {
525 : : }
526 : :
527 : : int
528 : : dwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
529 : : pid_t pid __attribute__ ((unused)),
530 : : bool assume_ptrace_stopped __attribute__ ((unused)))
531 : : {
532 : : return ENOSYS;
533 : : }
534 : : INTDEF (dwfl_linux_proc_attach)
535 : :
536 : : struct __libdwfl_pid_arg *
537 : : internal_function
538 : : __libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
539 : : {
540 : : return NULL;
541 : : }
542 : :
543 : : #endif /* ! __linux __ */
544 : :
|