blob: 8aee721169ee052f3a56ee6c27f27d7db6fe56be [file] [log] [blame]
Jan Kratochvil0b867462013-05-30 14:37:38 +02001/* Get Dwarf Frame state for target live PID process.
Mark Wielaard4b9e1432014-03-04 11:27:15 +01002 Copyright (C) 2013, 2014 Red Hat, Inc.
Jan Kratochvil0b867462013-05-30 14:37:38 +02003 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
Kurt Roeckx02cefda2014-04-22 21:46:22 +020040#ifdef __linux__
Jan Kratochvil0b867462013-05-30 14:37:38 +020041
42static bool
43linux_proc_pid_is_stopped (pid_t pid)
44{
45 char buffer[64];
46 FILE *procfile;
47 bool retval, have_state;
48
49 snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
50 procfile = fopen (buffer, "r");
51 if (procfile == NULL)
52 return false;
53
54 have_state = false;
55 while (fgets (buffer, sizeof (buffer), procfile) != NULL)
56 if (strncmp (buffer, "State:", 6) == 0)
57 {
58 have_state = true;
59 break;
60 }
61 retval = (have_state && strstr (buffer, "T (stopped)") != NULL);
62 fclose (procfile);
63 return retval;
64}
65
Mark Wielaard4b9e1432014-03-04 11:27:15 +010066bool
67internal_function
68__libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
Jan Kratochvil0b867462013-05-30 14:37:38 +020069{
70 if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
71 {
72 __libdwfl_seterrno (DWFL_E_ERRNO);
73 return false;
74 }
Jan Kratochvil10d7a392013-11-19 15:00:15 +010075 *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
76 if (*tid_was_stoppedp)
Jan Kratochvil0b867462013-05-30 14:37:38 +020077 {
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);
86 }
87 for (;;)
88 {
89 int status;
90 if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status))
91 {
92 int saved_errno = errno;
93 ptrace (PTRACE_DETACH, tid, NULL, NULL);
94 errno = saved_errno;
95 __libdwfl_seterrno (DWFL_E_ERRNO);
96 return false;
97 }
98 if (WSTOPSIG (status) == SIGSTOP)
99 break;
100 if (ptrace (PTRACE_CONT, tid, NULL,
101 (void *) (uintptr_t) WSTOPSIG (status)) != 0)
102 {
103 int saved_errno = errno;
104 ptrace (PTRACE_DETACH, tid, NULL, NULL);
105 errno = saved_errno;
106 __libdwfl_seterrno (DWFL_E_ERRNO);
107 return false;
108 }
109 }
110 return true;
111}
112
113static bool
114pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
115{
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100116 struct __libdwfl_pid_arg *pid_arg = arg;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200117 pid_t tid = pid_arg->tid_attached;
118 assert (tid > 0);
119 Dwfl_Process *process = dwfl->process;
120 if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
121 {
122#if SIZEOF_LONG == 8
123 errno = 0;
124 *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
125 return errno == 0;
126#else /* SIZEOF_LONG != 8 */
127 /* This should not happen. */
128 return false;
129#endif /* SIZEOF_LONG != 8 */
130 }
131#if 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;
135 if (lowered)
136 addr -= 4;
137#endif /* SIZEOF_LONG == 8 */
138 errno = 0;
139 *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
140 if (errno != 0)
141 return false;
142#if SIZEOF_LONG == 8
143# if BYTE_ORDER == BIG_ENDIAN
144 if (! lowered)
145 *result >>= 32;
146# else
147 if (lowered)
148 *result >>= 32;
149# endif
150#endif /* SIZEOF_LONG == 8 */
151 *result &= 0xffffffff;
152 return true;
153}
154
155static pid_t
156pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
157 void **thread_argp)
158{
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100159 struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200160 struct dirent *dirent;
Mark Wielaardc76b2ff2013-12-17 10:37:29 +0100161 /* Start fresh on first traversal. */
162 if (*thread_argp == NULL)
163 rewinddir (pid_arg->dir);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200164 do
165 {
166 errno = 0;
167 dirent = readdir (pid_arg->dir);
168 if (dirent == NULL)
169 {
170 if (errno != 0)
171 {
172 __libdwfl_seterrno (DWFL_E_ERRNO);
173 return -1;
174 }
175 return 0;
176 }
177 }
178 while (strcmp (dirent->d_name, ".") == 0
179 || strcmp (dirent->d_name, "..") == 0);
180 char *end;
181 errno = 0;
182 long tidl = strtol (dirent->d_name, &end, 10);
183 if (errno != 0)
184 {
185 __libdwfl_seterrno (DWFL_E_ERRNO);
186 return -1;
187 }
188 pid_t tid = tidl;
189 if (tidl <= 0 || (end && *end) || tid != tidl)
190 {
191 __libdwfl_seterrno (DWFL_E_PARSE_PROC);
192 return -1;
193 }
194 *thread_argp = dwfl_arg;
195 return tid;
196}
197
Mark Wielaarde962ec32013-12-20 10:09:12 +0100198/* Just checks that the thread id exists. */
199static bool
200pid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid,
201 void *dwfl_arg, void **thread_argp)
202{
203 *thread_argp = dwfl_arg;
204 if (kill (tid, 0) < 0)
205 {
206 __libdwfl_seterrno (DWFL_E_ERRNO);
207 return false;
208 }
209 return true;
210}
211
Jan Kratochvil0b867462013-05-30 14:37:38 +0200212/* Implement the ebl_set_initial_registers_tid setfunc callback. */
213
214static bool
Jan Kratochvil1c1a53b2013-11-14 20:55:41 +0100215pid_thread_state_registers_cb (int firstreg, unsigned nregs,
216 const Dwarf_Word *regs, void *arg)
Jan Kratochvil0b867462013-05-30 14:37:38 +0200217{
218 Dwfl_Thread *thread = (Dwfl_Thread *) arg;
Jan Kratochvil5cbf42a2013-12-15 18:56:17 +0100219 if (firstreg < 0)
220 {
221 assert (firstreg == -1);
222 assert (nregs == 1);
223 INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
224 return true;
225 }
226 assert (nregs > 0);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200227 return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
228}
229
230static bool
231pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
232{
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100233 struct __libdwfl_pid_arg *pid_arg = thread_arg;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200234 assert (pid_arg->tid_attached == 0);
235 pid_t tid = INTUSE(dwfl_thread_tid) (thread);
Mark Wielaard19108012013-12-30 22:00:57 +0100236 if (! pid_arg->assume_ptrace_stopped
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100237 && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
Jan Kratochvil0b867462013-05-30 14:37:38 +0200238 return false;
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);
244}
245
246static void
247pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
248{
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100249 struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200250 closedir (pid_arg->dir);
251 free (pid_arg);
252}
253
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100254void
255internal_function
256__libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
257{
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
262 PTRACE_DETACH. */
263 ptrace (PTRACE_DETACH, tid, NULL,
264 (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
265}
266
Jan Kratochvil0b867462013-05-30 14:37:38 +0200267static void
268pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
269{
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100270 struct __libdwfl_pid_arg *pid_arg = thread_arg;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200271 pid_t tid = INTUSE(dwfl_thread_tid) (thread);
272 assert (pid_arg->tid_attached == tid);
273 pid_arg->tid_attached = 0;
Mark Wielaard19108012013-12-30 22:00:57 +0100274 if (! pid_arg->assume_ptrace_stopped)
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100275 __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200276}
277
278static const Dwfl_Thread_Callbacks pid_thread_callbacks =
279{
280 pid_next_thread,
Mark Wielaarde962ec32013-12-20 10:09:12 +0100281 pid_getthread,
Jan Kratochvil0b867462013-05-30 14:37:38 +0200282 pid_memory_read,
283 pid_set_initial_registers,
284 pid_detach,
285 pid_thread_detach,
286};
287
Mark Wielaard19108012013-12-30 22:00:57 +0100288int
289dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
Jan Kratochvil0b867462013-05-30 14:37:38 +0200290{
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100291 char buffer[36];
292 FILE *procfile;
293
294 /* Make sure to report the actual PID (thread group leader) to
295 dwfl_attach_state. */
296 snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
297 procfile = fopen (buffer, "r");
298 if (procfile == NULL)
Mark Wielaard19108012013-12-30 22:00:57 +0100299 return errno;
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100300
301 char *line = NULL;
302 size_t linelen = 0;
303 while (getline (&line, &linelen, procfile) >= 0)
304 if (strncmp (line, "Tgid:", 5) == 0)
305 {
Mark Wielaard68de4422014-01-02 21:17:18 +0100306 errno = 0;
307 char *endptr;
308 long val = strtol (&line[5], &endptr, 10);
309 if ((errno == ERANGE && val == LONG_MAX)
310 || *endptr != '\n' || val < 0 || val != (pid_t) val)
311 pid = 0;
312 else
313 pid = (pid_t) val;
314 break;
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100315 }
316 free (line);
317 fclose (procfile);
318
319 if (pid == 0)
Mark Wielaard19108012013-12-30 22:00:57 +0100320 return ESRCH;
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100321
Jan Kratochvil0b867462013-05-30 14:37:38 +0200322 char dirname[64];
323 int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
324 assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
325 DIR *dir = opendir (dirname);
326 if (dir == NULL)
Mark Wielaard19108012013-12-30 22:00:57 +0100327 return errno;
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100328 struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200329 if (pid_arg == NULL)
330 {
331 closedir (dir);
Mark Wielaard19108012013-12-30 22:00:57 +0100332 return ENOMEM;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200333 }
334 pid_arg->dir = dir;
335 pid_arg->tid_attached = 0;
Mark Wielaard19108012013-12-30 22:00:57 +0100336 pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
Jan Kratochviled782372013-11-14 20:53:20 +0100337 if (! INTUSE(dwfl_attach_state) (dwfl, NULL, pid, &pid_thread_callbacks,
Jan Kratochvil0b867462013-05-30 14:37:38 +0200338 pid_arg))
339 {
340 closedir (dir);
341 free (pid_arg);
Mark Wielaard19108012013-12-30 22:00:57 +0100342 return -1;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200343 }
Mark Wielaard19108012013-12-30 22:00:57 +0100344 return 0;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200345}
Mark Wielaard19108012013-12-30 22:00:57 +0100346INTDEF (dwfl_linux_proc_attach)
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100347
348struct __libdwfl_pid_arg *
349internal_function
350__libdwfl_get_pid_arg (Dwfl *dwfl)
351{
352 if (dwfl != NULL && dwfl->process != NULL
353 && dwfl->process->callbacks == &pid_thread_callbacks)
354 return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;
355
356 return NULL;
357}
Kurt Roeckx02cefda2014-04-22 21:46:22 +0200358
359#else /* __linux__ */
360
361static pid_t
362pid_next_thread (Dwfl *dwfl __attribute__ ((unused)),
363 void *dwfl_arg __attribute__ ((unused)),
364 void **thread_argp __attribute__ ((unused)))
365{
366 errno = ENOSYS;
367 __libdwfl_seterrno (DWFL_E_ERRNO);
368 return -1;
369}
370
371static bool
372pid_getthread (Dwfl *dwfl __attribute__ ((unused)),
373 pid_t tid __attribute__ ((unused)),
374 void *dwfl_arg __attribute__ ((unused)),
375 void **thread_argp __attribute__ ((unused)))
376{
377 errno = ENOSYS;
378 __libdwfl_seterrno (DWFL_E_ERRNO);
379 return false;
380}
381
382static bool
383pid_memory_read (Dwfl *dwfl __attribute__ ((unused)),
384 Dwarf_Addr addr __attribute__ ((unused)),
385 Dwarf_Word *result __attribute__ ((unused)),
386 void *arg __attribute__ ((unused)))
387{
388 errno = ENOSYS;
389 __libdwfl_seterrno (DWFL_E_ERRNO);
390 return false;
391}
392
393static bool
394pid_set_initial_registers (Dwfl_Thread *thread __attribute__ ((unused)),
395 void *thread_arg __attribute__ ((unused)))
396{
397 errno = ENOSYS;
398 __libdwfl_seterrno (DWFL_E_ERRNO);
399 return false;
400}
401
402static void
403pid_detach (Dwfl *dwfl __attribute__ ((unused)),
404 void *dwfl_arg __attribute__ ((unused)))
405{
406}
407
408static void
409pid_thread_detach (Dwfl_Thread *thread __attribute__ ((unused)),
410 void *thread_arg __attribute__ ((unused)))
411{
412}
413
414static const Dwfl_Thread_Callbacks pid_thread_callbacks =
415{
416 pid_next_thread,
417 pid_getthread,
418 pid_memory_read,
419 pid_set_initial_registers,
420 pid_detach,
421 pid_thread_detach,
422};
423
424int
425dwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
426 pid_t pid __attribute__ ((unused)),
427 bool assume_ptrace_stopped __attribute__ ((unused)))
428{
429 return ENOSYS;
430}
431INTDEF (dwfl_linux_proc_attach)
432
433struct __libdwfl_pid_arg *
434internal_function
435__libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
436{
437 return NULL;
438}
439
440#endif /* ! __linux __ */
441