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 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 70bool 71internal_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 117static bool 118pid_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 159static pid_t 160pid_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. */ 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 216/* Implement the ebl_set_initial_registers_tid setfunc callback. */ 217 218static bool 219pid_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 234static bool 235pid_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 250static void 251pid_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 260void 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 273static void 274pid_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 284static 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 294int 295dwfl_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} 394INTDEF (dwfl_linux_proc_attach) 395 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} 406 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 430bool 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 440static 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 466void 467internal_function 468__libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)), 469 bool tid_was_stopped __attribute__ ((unused))) 470{ 471} 472 473static 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 507