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