blob: 4c0f42d8e9a8b1c198cd3be50e97bd3f1dcef721 [file] [log] [blame]
Jan Kratochvil0b867462013-05-30 14:37:38 +02001/* Get Dwarf Frame state for target live PID process.
Mark Wielaard87985092015-09-07 12:52:12 +02002 Copyright (C) 2013, 2014, 2015 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
Mark Wielaard87985092015-09-07 12:52:12 +020029#include "libelfP.h"
Jan Kratochvil0b867462013-05-30 14:37:38 +020030#include "libdwflP.h"
Mark Wielaard87985092015-09-07 12:52:12 +020031#include <sys/types.h>
32#include <sys/stat.h>
33#include <fcntl.h>
Jan Kratochvil0b867462013-05-30 14:37:38 +020034#include <sys/ptrace.h>
35#include <sys/wait.h>
36#include <dirent.h>
37#include <sys/syscall.h>
38#include <unistd.h>
39
40#ifndef MAX
41# define MAX(a, b) ((a) > (b) ? (a) : (b))
42#endif
43
Kurt Roeckx02cefda2014-04-22 21:46:22 +020044#ifdef __linux__
Jan Kratochvil0b867462013-05-30 14:37:38 +020045
46static bool
47linux_proc_pid_is_stopped (pid_t pid)
48{
49 char buffer[64];
50 FILE *procfile;
51 bool retval, have_state;
52
53 snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
54 procfile = fopen (buffer, "r");
55 if (procfile == NULL)
56 return false;
57
58 have_state = false;
59 while (fgets (buffer, sizeof (buffer), procfile) != NULL)
60 if (strncmp (buffer, "State:", 6) == 0)
61 {
62 have_state = true;
63 break;
64 }
65 retval = (have_state && strstr (buffer, "T (stopped)") != NULL);
66 fclose (procfile);
67 return retval;
68}
69
Mark Wielaard4b9e1432014-03-04 11:27:15 +010070bool
71internal_function
72__libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
Jan Kratochvil0b867462013-05-30 14:37:38 +020073{
74 if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
75 {
76 __libdwfl_seterrno (DWFL_E_ERRNO);
77 return false;
78 }
Jan Kratochvil10d7a392013-11-19 15:00:15 +010079 *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
80 if (*tid_was_stoppedp)
Jan Kratochvil0b867462013-05-30 14:37:38 +020081 {
82 /* Make sure there is a SIGSTOP signal pending even when the process is
83 already State: T (stopped). Older kernels might fail to generate
84 a SIGSTOP notification in that case in response to our PTRACE_ATTACH
85 above. Which would make the waitpid below wait forever. So emulate
86 it. Since there can only be one SIGSTOP notification pending this is
87 safe. See also gdb/linux-nat.c linux_nat_post_attach_wait. */
88 syscall (__NR_tkill, tid, SIGSTOP);
89 ptrace (PTRACE_CONT, tid, NULL, NULL);
90 }
91 for (;;)
92 {
93 int status;
94 if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status))
95 {
96 int saved_errno = errno;
97 ptrace (PTRACE_DETACH, tid, NULL, NULL);
98 errno = saved_errno;
99 __libdwfl_seterrno (DWFL_E_ERRNO);
100 return false;
101 }
102 if (WSTOPSIG (status) == SIGSTOP)
103 break;
104 if (ptrace (PTRACE_CONT, tid, NULL,
105 (void *) (uintptr_t) WSTOPSIG (status)) != 0)
106 {
107 int saved_errno = errno;
108 ptrace (PTRACE_DETACH, tid, NULL, NULL);
109 errno = saved_errno;
110 __libdwfl_seterrno (DWFL_E_ERRNO);
111 return false;
112 }
113 }
114 return true;
115}
116
117static bool
118pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
119{
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100120 struct __libdwfl_pid_arg *pid_arg = arg;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200121 pid_t tid = pid_arg->tid_attached;
122 assert (tid > 0);
123 Dwfl_Process *process = dwfl->process;
124 if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
125 {
126#if SIZEOF_LONG == 8
127 errno = 0;
128 *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
129 return errno == 0;
130#else /* SIZEOF_LONG != 8 */
131 /* This should not happen. */
132 return false;
133#endif /* SIZEOF_LONG != 8 */
134 }
135#if SIZEOF_LONG == 8
136 /* We do not care about reads unaliged to 4 bytes boundary.
137 But 0x...ffc read of 8 bytes could overrun a page. */
138 bool lowered = (addr & 4) != 0;
139 if (lowered)
140 addr -= 4;
141#endif /* SIZEOF_LONG == 8 */
142 errno = 0;
143 *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
144 if (errno != 0)
145 return false;
146#if SIZEOF_LONG == 8
147# if BYTE_ORDER == BIG_ENDIAN
148 if (! lowered)
149 *result >>= 32;
150# else
151 if (lowered)
152 *result >>= 32;
153# endif
154#endif /* SIZEOF_LONG == 8 */
155 *result &= 0xffffffff;
156 return true;
157}
158
159static pid_t
160pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
161 void **thread_argp)
162{
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100163 struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200164 struct dirent *dirent;
Mark Wielaardc76b2ff2013-12-17 10:37:29 +0100165 /* Start fresh on first traversal. */
166 if (*thread_argp == NULL)
167 rewinddir (pid_arg->dir);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200168 do
169 {
170 errno = 0;
171 dirent = readdir (pid_arg->dir);
172 if (dirent == NULL)
173 {
174 if (errno != 0)
175 {
176 __libdwfl_seterrno (DWFL_E_ERRNO);
177 return -1;
178 }
179 return 0;
180 }
181 }
182 while (strcmp (dirent->d_name, ".") == 0
183 || strcmp (dirent->d_name, "..") == 0);
184 char *end;
185 errno = 0;
186 long tidl = strtol (dirent->d_name, &end, 10);
187 if (errno != 0)
188 {
189 __libdwfl_seterrno (DWFL_E_ERRNO);
190 return -1;
191 }
192 pid_t tid = tidl;
193 if (tidl <= 0 || (end && *end) || tid != tidl)
194 {
195 __libdwfl_seterrno (DWFL_E_PARSE_PROC);
196 return -1;
197 }
198 *thread_argp = dwfl_arg;
199 return tid;
200}
201
Mark Wielaarde962ec32013-12-20 10:09:12 +0100202/* Just checks that the thread id exists. */
203static bool
204pid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid,
205 void *dwfl_arg, void **thread_argp)
206{
207 *thread_argp = dwfl_arg;
208 if (kill (tid, 0) < 0)
209 {
210 __libdwfl_seterrno (DWFL_E_ERRNO);
211 return false;
212 }
213 return true;
214}
215
Jan Kratochvil0b867462013-05-30 14:37:38 +0200216/* Implement the ebl_set_initial_registers_tid setfunc callback. */
217
218static bool
Jan Kratochvil1c1a53b2013-11-14 20:55:41 +0100219pid_thread_state_registers_cb (int firstreg, unsigned nregs,
220 const Dwarf_Word *regs, void *arg)
Jan Kratochvil0b867462013-05-30 14:37:38 +0200221{
222 Dwfl_Thread *thread = (Dwfl_Thread *) arg;
Jan Kratochvil5cbf42a2013-12-15 18:56:17 +0100223 if (firstreg < 0)
224 {
225 assert (firstreg == -1);
226 assert (nregs == 1);
227 INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
228 return true;
229 }
230 assert (nregs > 0);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200231 return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
232}
233
234static bool
235pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
236{
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100237 struct __libdwfl_pid_arg *pid_arg = thread_arg;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200238 assert (pid_arg->tid_attached == 0);
239 pid_t tid = INTUSE(dwfl_thread_tid) (thread);
Mark Wielaard19108012013-12-30 22:00:57 +0100240 if (! pid_arg->assume_ptrace_stopped
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100241 && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
Jan Kratochvil0b867462013-05-30 14:37:38 +0200242 return false;
243 pid_arg->tid_attached = tid;
244 Dwfl_Process *process = thread->process;
245 Ebl *ebl = process->ebl;
246 return ebl_set_initial_registers_tid (ebl, tid,
247 pid_thread_state_registers_cb, thread);
248}
249
250static void
251pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
252{
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100253 struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
Mark Wielaard87985092015-09-07 12:52:12 +0200254 elf_end (pid_arg->elf);
255 close (pid_arg->elf_fd);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200256 closedir (pid_arg->dir);
257 free (pid_arg);
258}
259
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100260void
261internal_function
262__libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
263{
264 /* This handling is needed only on older Linux kernels such as
265 2.6.32-358.23.2.el6.ppc64. Later kernels such as
266 3.11.7-200.fc19.x86_64 remember the T (stopped) state
267 themselves and no longer need to pass SIGSTOP during
268 PTRACE_DETACH. */
269 ptrace (PTRACE_DETACH, tid, NULL,
270 (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
271}
272
Jan Kratochvil0b867462013-05-30 14:37:38 +0200273static void
274pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
275{
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100276 struct __libdwfl_pid_arg *pid_arg = thread_arg;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200277 pid_t tid = INTUSE(dwfl_thread_tid) (thread);
278 assert (pid_arg->tid_attached == tid);
279 pid_arg->tid_attached = 0;
Mark Wielaard19108012013-12-30 22:00:57 +0100280 if (! pid_arg->assume_ptrace_stopped)
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100281 __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200282}
283
284static const Dwfl_Thread_Callbacks pid_thread_callbacks =
285{
286 pid_next_thread,
Mark Wielaarde962ec32013-12-20 10:09:12 +0100287 pid_getthread,
Jan Kratochvil0b867462013-05-30 14:37:38 +0200288 pid_memory_read,
289 pid_set_initial_registers,
290 pid_detach,
291 pid_thread_detach,
292};
293
Mark Wielaard19108012013-12-30 22:00:57 +0100294int
295dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
Jan Kratochvil0b867462013-05-30 14:37:38 +0200296{
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100297 char buffer[36];
298 FILE *procfile;
Mark Wielaard14beac32014-06-11 15:14:23 +0200299 int err = 0; /* The errno to return and set for dwfl->attcherr. */
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100300
301 /* Make sure to report the actual PID (thread group leader) to
302 dwfl_attach_state. */
303 snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
304 procfile = fopen (buffer, "r");
305 if (procfile == NULL)
Mark Wielaard14beac32014-06-11 15:14:23 +0200306 {
307 err = errno;
308 fail:
309 if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
310 {
311 errno = err;
312 dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
313 }
314 return err;
315 }
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100316
317 char *line = NULL;
318 size_t linelen = 0;
319 while (getline (&line, &linelen, procfile) >= 0)
320 if (strncmp (line, "Tgid:", 5) == 0)
321 {
Mark Wielaard68de4422014-01-02 21:17:18 +0100322 errno = 0;
323 char *endptr;
324 long val = strtol (&line[5], &endptr, 10);
325 if ((errno == ERANGE && val == LONG_MAX)
326 || *endptr != '\n' || val < 0 || val != (pid_t) val)
327 pid = 0;
328 else
329 pid = (pid_t) val;
330 break;
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100331 }
332 free (line);
333 fclose (procfile);
334
335 if (pid == 0)
Mark Wielaard14beac32014-06-11 15:14:23 +0200336 {
337 err = ESRCH;
338 goto fail;
339 }
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100340
Mark Wielaard87985092015-09-07 12:52:12 +0200341 char name[64];
342 int i = snprintf (name, sizeof (name), "/proc/%ld/task", (long) pid);
343 assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
344 DIR *dir = opendir (name);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200345 if (dir == NULL)
Mark Wielaard14beac32014-06-11 15:14:23 +0200346 {
347 err = errno;
348 goto fail;
349 }
Mark Wielaard87985092015-09-07 12:52:12 +0200350
351 Elf *elf;
352 i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid);
353 assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
354 int elf_fd = open (name, O_RDONLY);
355 if (elf_fd >= 0)
356 {
357 elf = elf_begin (elf_fd, ELF_C_READ_MMAP, NULL);
358 if (elf == NULL)
359 {
360 /* Just ignore, dwfl_attach_state will fall back to trying
361 to associate the Dwfl with one of the existing DWfl_Module
362 ELF images (to know the machine/class backend to use). */
363 close (elf_fd);
364 elf_fd = -1;
365 }
366 }
367 else
368 elf = NULL;
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100369 struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200370 if (pid_arg == NULL)
371 {
Mark Wielaard87985092015-09-07 12:52:12 +0200372 elf_end (elf);
373 close (elf_fd);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200374 closedir (dir);
Mark Wielaard14beac32014-06-11 15:14:23 +0200375 err = ENOMEM;
376 goto fail;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200377 }
378 pid_arg->dir = dir;
Mark Wielaard87985092015-09-07 12:52:12 +0200379 pid_arg->elf = elf;
380 pid_arg->elf_fd = elf_fd;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200381 pid_arg->tid_attached = 0;
Mark Wielaard19108012013-12-30 22:00:57 +0100382 pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
Mark Wielaard87985092015-09-07 12:52:12 +0200383 if (! INTUSE(dwfl_attach_state) (dwfl, elf, pid, &pid_thread_callbacks,
Jan Kratochvil0b867462013-05-30 14:37:38 +0200384 pid_arg))
385 {
Mark Wielaard87985092015-09-07 12:52:12 +0200386 elf_end (elf);
387 close (elf_fd);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200388 closedir (dir);
389 free (pid_arg);
Mark Wielaard19108012013-12-30 22:00:57 +0100390 return -1;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200391 }
Mark Wielaard19108012013-12-30 22:00:57 +0100392 return 0;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200393}
Mark Wielaard19108012013-12-30 22:00:57 +0100394INTDEF (dwfl_linux_proc_attach)
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100395
396struct __libdwfl_pid_arg *
397internal_function
398__libdwfl_get_pid_arg (Dwfl *dwfl)
399{
400 if (dwfl != NULL && dwfl->process != NULL
401 && dwfl->process->callbacks == &pid_thread_callbacks)
402 return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;
403
404 return NULL;
405}
Kurt Roeckx02cefda2014-04-22 21:46:22 +0200406
407#else /* __linux__ */
408
409static pid_t
410pid_next_thread (Dwfl *dwfl __attribute__ ((unused)),
411 void *dwfl_arg __attribute__ ((unused)),
412 void **thread_argp __attribute__ ((unused)))
413{
414 errno = ENOSYS;
415 __libdwfl_seterrno (DWFL_E_ERRNO);
416 return -1;
417}
418
419static bool
420pid_getthread (Dwfl *dwfl __attribute__ ((unused)),
421 pid_t tid __attribute__ ((unused)),
422 void *dwfl_arg __attribute__ ((unused)),
423 void **thread_argp __attribute__ ((unused)))
424{
425 errno = ENOSYS;
426 __libdwfl_seterrno (DWFL_E_ERRNO);
427 return false;
428}
429
Kurt Roeckxa7a38552014-06-24 22:08:36 +0200430bool
431internal_function
432__libdwfl_ptrace_attach (pid_t tid __attribute__ ((unused)),
433 bool *tid_was_stoppedp __attribute__ ((unused)))
434{
435 errno = ENOSYS;
436 __libdwfl_seterrno (DWFL_E_ERRNO);
437 return false;
438}
439
Kurt Roeckx02cefda2014-04-22 21:46:22 +0200440static bool
441pid_memory_read (Dwfl *dwfl __attribute__ ((unused)),
442 Dwarf_Addr addr __attribute__ ((unused)),
443 Dwarf_Word *result __attribute__ ((unused)),
444 void *arg __attribute__ ((unused)))
445{
446 errno = ENOSYS;
447 __libdwfl_seterrno (DWFL_E_ERRNO);
448 return false;
449}
450
451static bool
452pid_set_initial_registers (Dwfl_Thread *thread __attribute__ ((unused)),
453 void *thread_arg __attribute__ ((unused)))
454{
455 errno = ENOSYS;
456 __libdwfl_seterrno (DWFL_E_ERRNO);
457 return false;
458}
459
460static void
461pid_detach (Dwfl *dwfl __attribute__ ((unused)),
462 void *dwfl_arg __attribute__ ((unused)))
463{
464}
465
Kurt Roeckxa7a38552014-06-24 22:08:36 +0200466void
467internal_function
468__libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
469 bool tid_was_stopped __attribute__ ((unused)))
470{
471}
472
Kurt Roeckx02cefda2014-04-22 21:46:22 +0200473static void
474pid_thread_detach (Dwfl_Thread *thread __attribute__ ((unused)),
475 void *thread_arg __attribute__ ((unused)))
476{
477}
478
479static const Dwfl_Thread_Callbacks pid_thread_callbacks =
480{
481 pid_next_thread,
482 pid_getthread,
483 pid_memory_read,
484 pid_set_initial_registers,
485 pid_detach,
486 pid_thread_detach,
487};
488
489int
490dwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
491 pid_t pid __attribute__ ((unused)),
492 bool assume_ptrace_stopped __attribute__ ((unused)))
493{
494 return ENOSYS;
495}
496INTDEF (dwfl_linux_proc_attach)
497
498struct __libdwfl_pid_arg *
499internal_function
500__libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
501{
502 return NULL;
503}
504
505#endif /* ! __linux __ */
506