blob: 2e1d35923b47fa778c836939cfb8858ed023c2ea [file] [log] [blame]
Jan Kratochvil0b867462013-05-30 14:37:38 +02001/* Get Dwarf Frame state for target live PID process.
2 Copyright (C) 2013 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#include "libdwflP.h"
30#include <sys/ptrace.h>
31#include <sys/wait.h>
32#include <dirent.h>
33#include <sys/syscall.h>
34#include <unistd.h>
35
36#ifndef MAX
37# define MAX(a, b) ((a) > (b) ? (a) : (b))
38#endif
39
40struct pid_arg
41{
42 DIR *dir;
43 /* It is 0 if not used. */
44 pid_t tid_attached;
Jan Kratochvil10d7a392013-11-19 15:00:15 +010045 /* Valid only if TID_ATTACHED is not zero. */
46 bool tid_was_stopped;
Jan Kratochvil0b867462013-05-30 14:37:38 +020047};
48
49static bool
50linux_proc_pid_is_stopped (pid_t pid)
51{
52 char buffer[64];
53 FILE *procfile;
54 bool retval, have_state;
55
56 snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
57 procfile = fopen (buffer, "r");
58 if (procfile == NULL)
59 return false;
60
61 have_state = false;
62 while (fgets (buffer, sizeof (buffer), procfile) != NULL)
63 if (strncmp (buffer, "State:", 6) == 0)
64 {
65 have_state = true;
66 break;
67 }
68 retval = (have_state && strstr (buffer, "T (stopped)") != NULL);
69 fclose (procfile);
70 return retval;
71}
72
73static bool
Jan Kratochvil10d7a392013-11-19 15:00:15 +010074ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
Jan Kratochvil0b867462013-05-30 14:37:38 +020075{
76 if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
77 {
78 __libdwfl_seterrno (DWFL_E_ERRNO);
79 return false;
80 }
Jan Kratochvil10d7a392013-11-19 15:00:15 +010081 *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
82 if (*tid_was_stoppedp)
Jan Kratochvil0b867462013-05-30 14:37:38 +020083 {
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 syscall (__NR_tkill, tid, SIGSTOP);
91 ptrace (PTRACE_CONT, tid, NULL, NULL);
92 }
93 for (;;)
94 {
95 int status;
96 if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status))
97 {
98 int saved_errno = errno;
99 ptrace (PTRACE_DETACH, tid, NULL, NULL);
100 errno = saved_errno;
101 __libdwfl_seterrno (DWFL_E_ERRNO);
102 return false;
103 }
104 if (WSTOPSIG (status) == SIGSTOP)
105 break;
106 if (ptrace (PTRACE_CONT, tid, NULL,
107 (void *) (uintptr_t) WSTOPSIG (status)) != 0)
108 {
109 int saved_errno = errno;
110 ptrace (PTRACE_DETACH, tid, NULL, NULL);
111 errno = saved_errno;
112 __libdwfl_seterrno (DWFL_E_ERRNO);
113 return false;
114 }
115 }
116 return true;
117}
118
119static bool
120pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
121{
122 struct pid_arg *pid_arg = arg;
123 pid_t tid = pid_arg->tid_attached;
124 assert (tid > 0);
125 Dwfl_Process *process = dwfl->process;
126 if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
127 {
128#if SIZEOF_LONG == 8
129 errno = 0;
130 *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
131 return errno == 0;
132#else /* SIZEOF_LONG != 8 */
133 /* This should not happen. */
134 return false;
135#endif /* SIZEOF_LONG != 8 */
136 }
137#if SIZEOF_LONG == 8
138 /* We do not care about reads unaliged to 4 bytes boundary.
139 But 0x...ffc read of 8 bytes could overrun a page. */
140 bool lowered = (addr & 4) != 0;
141 if (lowered)
142 addr -= 4;
143#endif /* SIZEOF_LONG == 8 */
144 errno = 0;
145 *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
146 if (errno != 0)
147 return false;
148#if SIZEOF_LONG == 8
149# if BYTE_ORDER == BIG_ENDIAN
150 if (! lowered)
151 *result >>= 32;
152# else
153 if (lowered)
154 *result >>= 32;
155# endif
156#endif /* SIZEOF_LONG == 8 */
157 *result &= 0xffffffff;
158 return true;
159}
160
161static pid_t
162pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
163 void **thread_argp)
164{
165 struct pid_arg *pid_arg = dwfl_arg;
166 struct dirent *dirent;
Mark Wielaardc76b2ff2013-12-17 10:37:29 +0100167 /* Start fresh on first traversal. */
168 if (*thread_argp == NULL)
169 rewinddir (pid_arg->dir);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200170 do
171 {
172 errno = 0;
173 dirent = readdir (pid_arg->dir);
174 if (dirent == NULL)
175 {
176 if (errno != 0)
177 {
178 __libdwfl_seterrno (DWFL_E_ERRNO);
179 return -1;
180 }
181 return 0;
182 }
183 }
184 while (strcmp (dirent->d_name, ".") == 0
185 || strcmp (dirent->d_name, "..") == 0);
186 char *end;
187 errno = 0;
188 long tidl = strtol (dirent->d_name, &end, 10);
189 if (errno != 0)
190 {
191 __libdwfl_seterrno (DWFL_E_ERRNO);
192 return -1;
193 }
194 pid_t tid = tidl;
195 if (tidl <= 0 || (end && *end) || tid != tidl)
196 {
197 __libdwfl_seterrno (DWFL_E_PARSE_PROC);
198 return -1;
199 }
200 *thread_argp = dwfl_arg;
201 return tid;
202}
203
Mark Wielaarde962ec32013-12-20 10:09:12 +0100204/* Just checks that the thread id exists. */
205static bool
206pid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid,
207 void *dwfl_arg, void **thread_argp)
208{
209 *thread_argp = dwfl_arg;
210 if (kill (tid, 0) < 0)
211 {
212 __libdwfl_seterrno (DWFL_E_ERRNO);
213 return false;
214 }
215 return true;
216}
217
Jan Kratochvil0b867462013-05-30 14:37:38 +0200218/* Implement the ebl_set_initial_registers_tid setfunc callback. */
219
220static bool
Jan Kratochvil1c1a53b2013-11-14 20:55:41 +0100221pid_thread_state_registers_cb (int firstreg, unsigned nregs,
222 const Dwarf_Word *regs, void *arg)
Jan Kratochvil0b867462013-05-30 14:37:38 +0200223{
224 Dwfl_Thread *thread = (Dwfl_Thread *) arg;
Jan Kratochvil5cbf42a2013-12-15 18:56:17 +0100225 if (firstreg < 0)
226 {
227 assert (firstreg == -1);
228 assert (nregs == 1);
229 INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
230 return true;
231 }
232 assert (nregs > 0);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200233 return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
234}
235
236static bool
237pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
238{
239 struct pid_arg *pid_arg = thread_arg;
240 assert (pid_arg->tid_attached == 0);
241 pid_t tid = INTUSE(dwfl_thread_tid) (thread);
Jan Kratochvil10d7a392013-11-19 15:00:15 +0100242 if (! ptrace_attach (tid, &pid_arg->tid_was_stopped))
Jan Kratochvil0b867462013-05-30 14:37:38 +0200243 return false;
244 pid_arg->tid_attached = tid;
245 Dwfl_Process *process = thread->process;
246 Ebl *ebl = process->ebl;
247 return ebl_set_initial_registers_tid (ebl, tid,
248 pid_thread_state_registers_cb, thread);
249}
250
251static void
252pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
253{
254 struct pid_arg *pid_arg = dwfl_arg;
255 closedir (pid_arg->dir);
256 free (pid_arg);
257}
258
259static void
260pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
261{
262 struct pid_arg *pid_arg = thread_arg;
263 pid_t tid = INTUSE(dwfl_thread_tid) (thread);
264 assert (pid_arg->tid_attached == tid);
265 pid_arg->tid_attached = 0;
Jan Kratochvil10d7a392013-11-19 15:00:15 +0100266 /* This handling is needed only on older Linux kernels such as
267 2.6.32-358.23.2.el6.ppc64. Later kernels such as 3.11.7-200.fc19.x86_64
268 remember the T (stopped) state themselves and no longer need to pass
269 SIGSTOP during PTRACE_DETACH. */
270 ptrace (PTRACE_DETACH, tid, NULL,
271 (void *) (intptr_t) (pid_arg->tid_was_stopped ? SIGSTOP : 0));
Jan Kratochvil0b867462013-05-30 14:37:38 +0200272}
273
274static const Dwfl_Thread_Callbacks pid_thread_callbacks =
275{
276 pid_next_thread,
Mark Wielaarde962ec32013-12-20 10:09:12 +0100277 pid_getthread,
Jan Kratochvil0b867462013-05-30 14:37:38 +0200278 pid_memory_read,
279 pid_set_initial_registers,
280 pid_detach,
281 pid_thread_detach,
282};
283
284bool
285internal_function
286__libdwfl_attach_state_for_pid (Dwfl *dwfl, pid_t pid)
287{
288 char dirname[64];
289 int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
290 assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
291 DIR *dir = opendir (dirname);
292 if (dir == NULL)
293 {
294 __libdwfl_seterrno (DWFL_E_ERRNO);
295 return false;
296 }
297 struct pid_arg *pid_arg = malloc (sizeof *pid_arg);
298 if (pid_arg == NULL)
299 {
300 closedir (dir);
301 __libdwfl_seterrno (DWFL_E_NOMEM);
302 return false;
303 }
304 pid_arg->dir = dir;
305 pid_arg->tid_attached = 0;
Jan Kratochviled782372013-11-14 20:53:20 +0100306 if (! INTUSE(dwfl_attach_state) (dwfl, NULL, pid, &pid_thread_callbacks,
Jan Kratochvil0b867462013-05-30 14:37:38 +0200307 pid_arg))
308 {
309 closedir (dir);
310 free (pid_arg);
311 return false;
312 }
313 return true;
314}