• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* 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 #include "libelfP.h"
30 #include "libdwflP.h"
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #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 
44 #ifdef __linux__
45 
46 static bool
linux_proc_pid_is_stopped(pid_t pid)47 linux_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 
70 bool
71 internal_function
__libdwfl_ptrace_attach(pid_t tid,bool * tid_was_stoppedp)72 __libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
73 {
74   if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
75     {
76       __libdwfl_seterrno (DWFL_E_ERRNO);
77       return false;
78     }
79   *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
80   if (*tid_was_stoppedp)
81     {
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 
117 static bool
pid_memory_read(Dwfl * dwfl,Dwarf_Addr addr,Dwarf_Word * result,void * arg)118 pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
119 {
120   struct __libdwfl_pid_arg *pid_arg = arg;
121   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 
159 static pid_t
pid_next_thread(Dwfl * dwfl,void * dwfl_arg,void ** thread_argp)160 pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
161 		 void **thread_argp)
162 {
163   struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
164   struct dirent *dirent;
165   /* Start fresh on first traversal. */
166   if (*thread_argp == NULL)
167     rewinddir (pid_arg->dir);
168   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 
202 /* Just checks that the thread id exists.  */
203 static bool
pid_getthread(Dwfl * dwfl,pid_t tid,void * dwfl_arg,void ** thread_argp)204 pid_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 
216 /* Implement the ebl_set_initial_registers_tid setfunc callback.  */
217 
218 static bool
pid_thread_state_registers_cb(int firstreg,unsigned nregs,const Dwarf_Word * regs,void * arg)219 pid_thread_state_registers_cb (int firstreg, unsigned nregs,
220 			       const Dwarf_Word *regs, void *arg)
221 {
222   Dwfl_Thread *thread = (Dwfl_Thread *) arg;
223   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);
231   return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
232 }
233 
234 static bool
pid_set_initial_registers(Dwfl_Thread * thread,void * thread_arg)235 pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
236 {
237   struct __libdwfl_pid_arg *pid_arg = thread_arg;
238   assert (pid_arg->tid_attached == 0);
239   pid_t tid = INTUSE(dwfl_thread_tid) (thread);
240   if (! pid_arg->assume_ptrace_stopped
241       && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
242     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 
250 static void
pid_detach(Dwfl * dwfl,void * dwfl_arg)251 pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
252 {
253   struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
254   elf_end (pid_arg->elf);
255   close (pid_arg->elf_fd);
256   closedir (pid_arg->dir);
257   free (pid_arg);
258 }
259 
260 void
261 internal_function
__libdwfl_ptrace_detach(pid_t tid,bool tid_was_stopped)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 
273 static void
pid_thread_detach(Dwfl_Thread * thread,void * thread_arg)274 pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
275 {
276   struct __libdwfl_pid_arg *pid_arg = thread_arg;
277   pid_t tid = INTUSE(dwfl_thread_tid) (thread);
278   assert (pid_arg->tid_attached == tid);
279   pid_arg->tid_attached = 0;
280   if (! pid_arg->assume_ptrace_stopped)
281     __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
282 }
283 
284 static const Dwfl_Thread_Callbacks pid_thread_callbacks =
285 {
286   pid_next_thread,
287   pid_getthread,
288   pid_memory_read,
289   pid_set_initial_registers,
290   pid_detach,
291   pid_thread_detach,
292 };
293 
294 int
dwfl_linux_proc_attach(Dwfl * dwfl,pid_t pid,bool assume_ptrace_stopped)295 dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
296 {
297   char buffer[36];
298   FILE *procfile;
299   int err = 0; /* The errno to return and set for dwfl->attcherr.  */
300 
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)
306     {
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     }
316 
317   char *line = NULL;
318   size_t linelen = 0;
319   while (getline (&line, &linelen, procfile) >= 0)
320     if (strncmp (line, "Tgid:", 5) == 0)
321       {
322 	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;
331       }
332   free (line);
333   fclose (procfile);
334 
335   if (pid == 0)
336     {
337       err = ESRCH;
338       goto fail;
339     }
340 
341   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);
345   if (dir == NULL)
346     {
347       err = errno;
348       goto fail;
349     }
350 
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;
369   struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
370   if (pid_arg == NULL)
371     {
372       elf_end (elf);
373       close (elf_fd);
374       closedir (dir);
375       err = ENOMEM;
376       goto fail;
377     }
378   pid_arg->dir = dir;
379   pid_arg->elf = elf;
380   pid_arg->elf_fd = elf_fd;
381   pid_arg->tid_attached = 0;
382   pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
383   if (! INTUSE(dwfl_attach_state) (dwfl, elf, pid, &pid_thread_callbacks,
384 				   pid_arg))
385     {
386       elf_end (elf);
387       close (elf_fd);
388       closedir (dir);
389       free (pid_arg);
390       return -1;
391     }
392   return 0;
393 }
INTDEF(dwfl_linux_proc_attach)394 INTDEF (dwfl_linux_proc_attach)
395 
396 struct __libdwfl_pid_arg *
397 internal_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 }
406 
407 #else	/* __linux__ */
408 
409 static pid_t
pid_next_thread(Dwfl * dwfl,void * dwfl_arg,void ** thread_argp)410 pid_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 
419 static bool
pid_getthread(Dwfl * dwfl,pid_t tid,void * dwfl_arg,void ** thread_argp)420 pid_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 
430 bool
431 internal_function
__libdwfl_ptrace_attach(pid_t tid,bool * tid_was_stoppedp)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 
440 static bool
pid_memory_read(Dwfl * dwfl,Dwarf_Addr addr,Dwarf_Word * result,void * arg)441 pid_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 
451 static bool
pid_set_initial_registers(Dwfl_Thread * thread,void * thread_arg)452 pid_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 
460 static void
pid_detach(Dwfl * dwfl,void * dwfl_arg)461 pid_detach (Dwfl *dwfl __attribute__ ((unused)),
462 	    void *dwfl_arg __attribute__ ((unused)))
463 {
464 }
465 
466 void
467 internal_function
__libdwfl_ptrace_detach(pid_t tid,bool tid_was_stopped)468 __libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
469 			 bool tid_was_stopped __attribute__ ((unused)))
470 {
471 }
472 
473 static void
pid_thread_detach(Dwfl_Thread * thread,void * thread_arg)474 pid_thread_detach (Dwfl_Thread *thread __attribute__ ((unused)),
475 		  void *thread_arg __attribute__ ((unused)))
476 {
477 }
478 
479 static 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 
489 int
dwfl_linux_proc_attach(Dwfl * dwfl,pid_t pid,bool assume_ptrace_stopped)490 dwfl_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 }
INTDEF(dwfl_linux_proc_attach)496 INTDEF (dwfl_linux_proc_attach)
497 
498 struct __libdwfl_pid_arg *
499 internal_function
500 __libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
501 {
502   return NULL;
503 }
504 
505 #endif /* ! __linux __ */
506 
507