1 /* Get Dwarf Frame state for target live PID process.
2 Copyright (C) 2013, 2014 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
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
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
18 or both in parallel, as here.
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.
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/>. */
30 #include <sys/ptrace.h>
33 #include <sys/syscall.h>
37 # define MAX(a, b) ((a) > (b) ? (a) : (b))
43 linux_proc_pid_is_stopped (pid_t pid)
47 bool retval, have_state;
49 snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
50 procfile = fopen (buffer, "r");
55 while (fgets (buffer, sizeof (buffer), procfile) != NULL)
56 if (strncmp (buffer, "State:", 6) == 0)
61 retval = (have_state && strstr (buffer, "T (stopped)") != NULL);
68 __libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
70 if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
72 __libdwfl_seterrno (DWFL_E_ERRNO);
75 *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
76 if (*tid_was_stoppedp)
78 /* Make sure there is a SIGSTOP signal pending even when the process is
79 already State: T (stopped). Older kernels might fail to generate
80 a SIGSTOP notification in that case in response to our PTRACE_ATTACH
81 above. Which would make the waitpid below wait forever. So emulate
82 it. Since there can only be one SIGSTOP notification pending this is
83 safe. See also gdb/linux-nat.c linux_nat_post_attach_wait. */
84 syscall (__NR_tkill, tid, SIGSTOP);
85 ptrace (PTRACE_CONT, tid, NULL, NULL);
90 if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status))
92 int saved_errno = errno;
93 ptrace (PTRACE_DETACH, tid, NULL, NULL);
95 __libdwfl_seterrno (DWFL_E_ERRNO);
98 if (WSTOPSIG (status) == SIGSTOP)
100 if (ptrace (PTRACE_CONT, tid, NULL,
101 (void *) (uintptr_t) WSTOPSIG (status)) != 0)
103 int saved_errno = errno;
104 ptrace (PTRACE_DETACH, tid, NULL, NULL);
106 __libdwfl_seterrno (DWFL_E_ERRNO);
114 pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
116 struct __libdwfl_pid_arg *pid_arg = arg;
117 pid_t tid = pid_arg->tid_attached;
119 Dwfl_Process *process = dwfl->process;
120 if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
124 *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
126 #else /* SIZEOF_LONG != 8 */
127 /* This should not happen. */
129 #endif /* SIZEOF_LONG != 8 */
132 /* We do not care about reads unaliged to 4 bytes boundary.
133 But 0x...ffc read of 8 bytes could overrun a page. */
134 bool lowered = (addr & 4) != 0;
137 #endif /* SIZEOF_LONG == 8 */
139 *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
143 # if BYTE_ORDER == BIG_ENDIAN
150 #endif /* SIZEOF_LONG == 8 */
151 *result &= 0xffffffff;
156 pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
159 struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
160 struct dirent *dirent;
161 /* Start fresh on first traversal. */
162 if (*thread_argp == NULL)
163 rewinddir (pid_arg->dir);
167 dirent = readdir (pid_arg->dir);
172 __libdwfl_seterrno (DWFL_E_ERRNO);
178 while (strcmp (dirent->d_name, ".") == 0
179 || strcmp (dirent->d_name, "..") == 0);
182 long tidl = strtol (dirent->d_name, &end, 10);
185 __libdwfl_seterrno (DWFL_E_ERRNO);
189 if (tidl <= 0 || (end && *end) || tid != tidl)
191 __libdwfl_seterrno (DWFL_E_PARSE_PROC);
194 *thread_argp = dwfl_arg;
198 /* Just checks that the thread id exists. */
200 pid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid,
201 void *dwfl_arg, void **thread_argp)
203 *thread_argp = dwfl_arg;
204 if (kill (tid, 0) < 0)
206 __libdwfl_seterrno (DWFL_E_ERRNO);
212 /* Implement the ebl_set_initial_registers_tid setfunc callback. */
215 pid_thread_state_registers_cb (int firstreg, unsigned nregs,
216 const Dwarf_Word *regs, void *arg)
218 Dwfl_Thread *thread = (Dwfl_Thread *) arg;
221 assert (firstreg == -1);
223 INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
227 return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
231 pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
233 struct __libdwfl_pid_arg *pid_arg = thread_arg;
234 assert (pid_arg->tid_attached == 0);
235 pid_t tid = INTUSE(dwfl_thread_tid) (thread);
236 if (! pid_arg->assume_ptrace_stopped
237 && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
239 pid_arg->tid_attached = tid;
240 Dwfl_Process *process = thread->process;
241 Ebl *ebl = process->ebl;
242 return ebl_set_initial_registers_tid (ebl, tid,
243 pid_thread_state_registers_cb, thread);
247 pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
249 struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
250 closedir (pid_arg->dir);
256 __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
258 /* This handling is needed only on older Linux kernels such as
259 2.6.32-358.23.2.el6.ppc64. Later kernels such as
260 3.11.7-200.fc19.x86_64 remember the T (stopped) state
261 themselves and no longer need to pass SIGSTOP during
263 ptrace (PTRACE_DETACH, tid, NULL,
264 (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
268 pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
270 struct __libdwfl_pid_arg *pid_arg = thread_arg;
271 pid_t tid = INTUSE(dwfl_thread_tid) (thread);
272 assert (pid_arg->tid_attached == tid);
273 pid_arg->tid_attached = 0;
274 if (! pid_arg->assume_ptrace_stopped)
275 __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
278 static const Dwfl_Thread_Callbacks pid_thread_callbacks =
283 pid_set_initial_registers,
289 dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
293 int err = 0; /* The errno to return and set for dwfl->attcherr. */
295 /* Make sure to report the actual PID (thread group leader) to
296 dwfl_attach_state. */
297 snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
298 procfile = fopen (buffer, "r");
299 if (procfile == NULL)
303 if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
306 dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
313 while (getline (&line, &linelen, procfile) >= 0)
314 if (strncmp (line, "Tgid:", 5) == 0)
318 long val = strtol (&line[5], &endptr, 10);
319 if ((errno == ERANGE && val == LONG_MAX)
320 || *endptr != '\n' || val < 0 || val != (pid_t) val)
336 int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
337 assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
338 DIR *dir = opendir (dirname);
344 struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
352 pid_arg->tid_attached = 0;
353 pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
354 if (! INTUSE(dwfl_attach_state) (dwfl, NULL, pid, &pid_thread_callbacks,
363 INTDEF (dwfl_linux_proc_attach)
365 struct __libdwfl_pid_arg *
367 __libdwfl_get_pid_arg (Dwfl *dwfl)
369 if (dwfl != NULL && dwfl->process != NULL
370 && dwfl->process->callbacks == &pid_thread_callbacks)
371 return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;
376 #else /* __linux__ */
379 pid_next_thread (Dwfl *dwfl __attribute__ ((unused)),
380 void *dwfl_arg __attribute__ ((unused)),
381 void **thread_argp __attribute__ ((unused)))
384 __libdwfl_seterrno (DWFL_E_ERRNO);
389 pid_getthread (Dwfl *dwfl __attribute__ ((unused)),
390 pid_t tid __attribute__ ((unused)),
391 void *dwfl_arg __attribute__ ((unused)),
392 void **thread_argp __attribute__ ((unused)))
395 __libdwfl_seterrno (DWFL_E_ERRNO);
401 __libdwfl_ptrace_attach (pid_t tid __attribute__ ((unused)),
402 bool *tid_was_stoppedp __attribute__ ((unused)))
405 __libdwfl_seterrno (DWFL_E_ERRNO);
410 pid_memory_read (Dwfl *dwfl __attribute__ ((unused)),
411 Dwarf_Addr addr __attribute__ ((unused)),
412 Dwarf_Word *result __attribute__ ((unused)),
413 void *arg __attribute__ ((unused)))
416 __libdwfl_seterrno (DWFL_E_ERRNO);
421 pid_set_initial_registers (Dwfl_Thread *thread __attribute__ ((unused)),
422 void *thread_arg __attribute__ ((unused)))
425 __libdwfl_seterrno (DWFL_E_ERRNO);
430 pid_detach (Dwfl *dwfl __attribute__ ((unused)),
431 void *dwfl_arg __attribute__ ((unused)))
437 __libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
438 bool tid_was_stopped __attribute__ ((unused)))
443 pid_thread_detach (Dwfl_Thread *thread __attribute__ ((unused)),
444 void *thread_arg __attribute__ ((unused)))
448 static const Dwfl_Thread_Callbacks pid_thread_callbacks =
453 pid_set_initial_registers,
459 dwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
460 pid_t pid __attribute__ ((unused)),
461 bool assume_ptrace_stopped __attribute__ ((unused)))
465 INTDEF (dwfl_linux_proc_attach)
467 struct __libdwfl_pid_arg *
469 __libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
474 #endif /* ! __linux __ */