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