Home | History | Annotate | Download | only in libdwfl
      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
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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 }
    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
    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
    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
    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
    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
    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
    461 pid_detach (Dwfl *dwfl __attribute__ ((unused)),
    462 	    void *dwfl_arg __attribute__ ((unused)))
    463 {
    464 }
    465 
    466 void
    467 internal_function
    468 __libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
    469 			 bool tid_was_stopped __attribute__ ((unused)))
    470 {
    471 }
    472 
    473 static void
    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
    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 }
    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