blob: ae7170286f328b558c83f1cceb4e8ca2c8beb4ff [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;
Mark Wielaard14beac32014-06-11 15:14:23 +0200293 int err = 0; /* The errno to return and set for dwfl->attcherr. */
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100294
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)
Mark Wielaard14beac32014-06-11 15:14:23 +0200300 {
301 err = errno;
302 fail:
303 if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
304 {
305 errno = err;
306 dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
307 }
308 return err;
309 }
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100310
311 char *line = NULL;
312 size_t linelen = 0;
313 while (getline (&line, &linelen, procfile) >= 0)
314 if (strncmp (line, "Tgid:", 5) == 0)
315 {
Mark Wielaard68de4422014-01-02 21:17:18 +0100316 errno = 0;
317 char *endptr;
318 long val = strtol (&line[5], &endptr, 10);
319 if ((errno == ERANGE && val == LONG_MAX)
320 || *endptr != '\n' || val < 0 || val != (pid_t) val)
321 pid = 0;
322 else
323 pid = (pid_t) val;
324 break;
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100325 }
326 free (line);
327 fclose (procfile);
328
329 if (pid == 0)
Mark Wielaard14beac32014-06-11 15:14:23 +0200330 {
331 err = ESRCH;
332 goto fail;
333 }
Mark Wielaard97bbf9b2013-12-23 14:20:06 +0100334
Jan Kratochvil0b867462013-05-30 14:37:38 +0200335 char dirname[64];
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);
339 if (dir == NULL)
Mark Wielaard14beac32014-06-11 15:14:23 +0200340 {
341 err = errno;
342 goto fail;
343 }
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100344 struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
Jan Kratochvil0b867462013-05-30 14:37:38 +0200345 if (pid_arg == NULL)
346 {
347 closedir (dir);
Mark Wielaard14beac32014-06-11 15:14:23 +0200348 err = ENOMEM;
349 goto fail;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200350 }
351 pid_arg->dir = dir;
352 pid_arg->tid_attached = 0;
Mark Wielaard19108012013-12-30 22:00:57 +0100353 pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
Jan Kratochviled782372013-11-14 20:53:20 +0100354 if (! INTUSE(dwfl_attach_state) (dwfl, NULL, pid, &pid_thread_callbacks,
Jan Kratochvil0b867462013-05-30 14:37:38 +0200355 pid_arg))
356 {
357 closedir (dir);
358 free (pid_arg);
Mark Wielaard19108012013-12-30 22:00:57 +0100359 return -1;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200360 }
Mark Wielaard19108012013-12-30 22:00:57 +0100361 return 0;
Jan Kratochvil0b867462013-05-30 14:37:38 +0200362}
Mark Wielaard19108012013-12-30 22:00:57 +0100363INTDEF (dwfl_linux_proc_attach)
Mark Wielaard4b9e1432014-03-04 11:27:15 +0100364
365struct __libdwfl_pid_arg *
366internal_function
367__libdwfl_get_pid_arg (Dwfl *dwfl)
368{
369 if (dwfl != NULL && dwfl->process != NULL
370 && dwfl->process->callbacks == &pid_thread_callbacks)
371 return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;
372
373 return NULL;
374}
Kurt Roeckx02cefda2014-04-22 21:46:22 +0200375
376#else /* __linux__ */
377
378static pid_t
379pid_next_thread (Dwfl *dwfl __attribute__ ((unused)),
380 void *dwfl_arg __attribute__ ((unused)),
381 void **thread_argp __attribute__ ((unused)))
382{
383 errno = ENOSYS;
384 __libdwfl_seterrno (DWFL_E_ERRNO);
385 return -1;
386}
387
388static bool
389pid_getthread (Dwfl *dwfl __attribute__ ((unused)),
390 pid_t tid __attribute__ ((unused)),
391 void *dwfl_arg __attribute__ ((unused)),
392 void **thread_argp __attribute__ ((unused)))
393{
394 errno = ENOSYS;
395 __libdwfl_seterrno (DWFL_E_ERRNO);
396 return false;
397}
398
Kurt Roeckxa7a38552014-06-24 22:08:36 +0200399bool
400internal_function
401__libdwfl_ptrace_attach (pid_t tid __attribute__ ((unused)),
402 bool *tid_was_stoppedp __attribute__ ((unused)))
403{
404 errno = ENOSYS;
405 __libdwfl_seterrno (DWFL_E_ERRNO);
406 return false;
407}
408
Kurt Roeckx02cefda2014-04-22 21:46:22 +0200409static bool
410pid_memory_read (Dwfl *dwfl __attribute__ ((unused)),
411 Dwarf_Addr addr __attribute__ ((unused)),
412 Dwarf_Word *result __attribute__ ((unused)),
413 void *arg __attribute__ ((unused)))
414{
415 errno = ENOSYS;
416 __libdwfl_seterrno (DWFL_E_ERRNO);
417 return false;
418}
419
420static bool
421pid_set_initial_registers (Dwfl_Thread *thread __attribute__ ((unused)),
422 void *thread_arg __attribute__ ((unused)))
423{
424 errno = ENOSYS;
425 __libdwfl_seterrno (DWFL_E_ERRNO);
426 return false;
427}
428
429static void
430pid_detach (Dwfl *dwfl __attribute__ ((unused)),
431 void *dwfl_arg __attribute__ ((unused)))
432{
433}
434
Kurt Roeckxa7a38552014-06-24 22:08:36 +0200435void
436internal_function
437__libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
438 bool tid_was_stopped __attribute__ ((unused)))
439{
440}
441
Kurt Roeckx02cefda2014-04-22 21:46:22 +0200442static void
443pid_thread_detach (Dwfl_Thread *thread __attribute__ ((unused)),
444 void *thread_arg __attribute__ ((unused)))
445{
446}
447
448static const Dwfl_Thread_Callbacks pid_thread_callbacks =
449{
450 pid_next_thread,
451 pid_getthread,
452 pid_memory_read,
453 pid_set_initial_registers,
454 pid_detach,
455 pid_thread_detach,
456};
457
458int
459dwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
460 pid_t pid __attribute__ ((unused)),
461 bool assume_ptrace_stopped __attribute__ ((unused)))
462{
463 return ENOSYS;
464}
465INTDEF (dwfl_linux_proc_attach)
466
467struct __libdwfl_pid_arg *
468internal_function
469__libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
470{
471 return NULL;
472}
473
474#endif /* ! __linux __ */
475