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