1 /* 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifdef INCLUDE_SA_ATTACH 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <signal.h> 31 #include <errno.h> 32 #include <elf.h> 33 #include <sys/types.h> 34 #include <sys/wait.h> 35 #include <sys/ptrace.h> 36 #include <sys/uio.h> 37 #include "libproc_impl.h" 38 39 #if defined(x86_64) && !defined(amd64) 40 #define amd64 1 41 #endif 42 43 #ifndef __WALL 44 #define __WALL 0x40000000 // Copied from /usr/include/linux/wait.h 45 #endif 46 47 // This file has the libproc implementation specific to live process 48 // For core files, refer to ps_core.c 49 50 static inline uintptr_t align(uintptr_t ptr, size_t size) { 51 return (ptr & ~(size - 1)); 52 } 53 54 // --------------------------------------------- 55 // ptrace functions 56 // --------------------------------------------- 203 break; 204 case ECHILD: 205 print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid); 206 break; 207 case EINVAL: 208 print_debug("waitpid() failed. Invalid options argument.\n"); 209 break; 210 default: 211 print_debug("waitpid() failed. Unexpected error %d\n",errno); 212 break; 213 } 214 return false; 215 } 216 } 217 } 218 219 // attach to a process/thread specified by "pid" 220 static bool ptrace_attach(pid_t pid, char* err_buf, size_t err_buf_len) { 221 if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) { 222 char buf[200]; 223 char* msg = strerror_r(errno, buf, sizeof(buf)); 224 snprintf(err_buf, err_buf_len, "ptrace(PTRACE_ATTACH, ..) failed for %d: %s", pid, msg); 225 print_debug("%s\n", err_buf); 226 return false; 227 } else { 228 return ptrace_waitpid(pid); 229 } 230 } 231 232 // ------------------------------------------------------- 233 // functions for obtaining library information 234 // ------------------------------------------------------- 235 236 /* 237 * splits a string _str_ into substrings with delimiter _delim_ by replacing old * delimiters with _new_delim_ (ideally, '\0'). the address of each substring 238 * is stored in array _ptrs_ as the return value. the maximum capacity of _ptrs_ * array is specified by parameter _n_. 239 * RETURN VALUE: total number of substrings (always <= _n_) 240 * NOTE: string _str_ is modified if _delim_!=_new_delim_ 241 */ 242 static int split_n_str(char * str, int n, char ** ptrs, char delim, char new_delim) 243 { 244 int i; 245 for(i = 0; i < n; i++) ptrs[i] = NULL; 384 print_debug("%s\n", err_buf); 385 return NULL; 386 } 387 388 if (ptrace_attach(pid, err_buf, err_buf_len) != true) { 389 free(ph); 390 return NULL; 391 } 392 393 // initialize ps_prochandle 394 ph->pid = pid; 395 396 // initialize vtable 397 ph->ops = &process_ops; 398 399 // read library info and symbol tables, must do this before attaching threads, 400 // as the symbols in the pthread library will be used to figure out 401 // the list of threads within the same process. 402 read_lib_info(ph); 403 404 // read thread info 405 read_thread_info(ph, add_new_thread); 406 407 // attach to the threads 408 thr = ph->threads; 409 while (thr) { 410 // don't attach to the main thread again 411 if (ph->pid != thr->lwp_id && ptrace_attach(thr->lwp_id, err_buf, err_buf_len) != true) { 412 // even if one attach fails, we get return NULL 413 Prelease(ph); 414 return NULL; 415 } 416 thr = thr->next; 417 } 418 return ph; 419 } 420 421 #endif // INCLUDE_SA_ATTACH | 1 /* 2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <signal.h> 29 #include <errno.h> 30 #include <elf.h> 31 #include <sys/types.h> 32 #include <sys/wait.h> 33 #include <sys/ptrace.h> 34 #include <sys/uio.h> 35 #ifndef INCLUDE_SA_ATTACH 36 #include <dirent.h> 37 #endif 38 #include "libproc_impl.h" 39 40 #if defined(x86_64) && !defined(amd64) 41 #define amd64 1 42 #endif 43 44 #ifndef __WALL 45 #define __WALL 0x40000000 // Copied from /usr/include/linux/wait.h 46 #endif 47 48 // This file has the libproc implementation specific to live process 49 // For core files, refer to ps_core.c 50 51 static inline uintptr_t align(uintptr_t ptr, size_t size) { 52 return (ptr & ~(size - 1)); 53 } 54 55 // --------------------------------------------- 56 // ptrace functions 57 // --------------------------------------------- 204 break; 205 case ECHILD: 206 print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid); 207 break; 208 case EINVAL: 209 print_debug("waitpid() failed. Invalid options argument.\n"); 210 break; 211 default: 212 print_debug("waitpid() failed. Unexpected error %d\n",errno); 213 break; 214 } 215 return false; 216 } 217 } 218 } 219 220 // attach to a process/thread specified by "pid" 221 static bool ptrace_attach(pid_t pid, char* err_buf, size_t err_buf_len) { 222 if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) { 223 char buf[200]; 224 if (strerror_r(errno, buf, sizeof(buf) == 0)) { 225 snprintf(err_buf, err_buf_len, 226 "ptrace(PTRACE_ATTACH, ..) failed for %d: %s", pid, buf); 227 print_debug("%s\n", err_buf); 228 } 229 return false; 230 } else { 231 return ptrace_waitpid(pid); 232 } 233 } 234 235 // ------------------------------------------------------- 236 // functions for obtaining library information 237 // ------------------------------------------------------- 238 239 /* 240 * splits a string _str_ into substrings with delimiter _delim_ by replacing old * delimiters with _new_delim_ (ideally, '\0'). the address of each substring 241 * is stored in array _ptrs_ as the return value. the maximum capacity of _ptrs_ * array is specified by parameter _n_. 242 * RETURN VALUE: total number of substrings (always <= _n_) 243 * NOTE: string _str_ is modified if _delim_!=_new_delim_ 244 */ 245 static int split_n_str(char * str, int n, char ** ptrs, char delim, char new_delim) 246 { 247 int i; 248 for(i = 0; i < n; i++) ptrs[i] = NULL; 387 print_debug("%s\n", err_buf); 388 return NULL; 389 } 390 391 if (ptrace_attach(pid, err_buf, err_buf_len) != true) { 392 free(ph); 393 return NULL; 394 } 395 396 // initialize ps_prochandle 397 ph->pid = pid; 398 399 // initialize vtable 400 ph->ops = &process_ops; 401 402 // read library info and symbol tables, must do this before attaching threads, 403 // as the symbols in the pthread library will be used to figure out 404 // the list of threads within the same process. 405 read_lib_info(ph); 406 407 #ifdef INCLUDE_SA_ATTACH 408 // read thread info 409 read_thread_info(ph, add_new_thread); 410 411 // attach to the threads 412 thr = ph->threads; 413 while (thr) { 414 // don't attach to the main thread again 415 if (pid != thr->lwp_id && ptrace_attach(thr->lwp_id, err_buf, err_buf_len) != true) { 416 // even if one attach fails, we get return NULL 417 Prelease(ph); 418 return NULL; 419 } 420 thr = thr->next; 421 } 422 #else 423 DIR *dir = NULL; 424 struct dirent *ent = NULL; 425 char taskpath[80]; 426 427 // Find the lwpids to attach to by traversing the /proc/<pid>/task/ directory, 428 // and attach to those. 429 snprintf (taskpath, sizeof (taskpath), "/proc/%ld/task", (unsigned long) pid); 430 if ((dir = opendir(taskpath)) != NULL) { 431 while ((ent = readdir (dir)) != NULL) { 432 unsigned long lwp; 433 434 if ((lwp = strtoul (ent->d_name, NULL, 10)) != 0) { 435 add_new_thread (ph, 0, lwp); 436 437 // Don't attach to the main thread again 438 if (lwp == (unsigned long) pid) { 439 continue; 440 } 441 442 if (ptrace_attach(lwp, err_buf, err_buf_len) != true) { 443 Prelease(ph); 444 closedir (dir); 445 return NULL; 446 } 447 } 448 } 449 } else { 450 print_debug("Could not open /proc/%ld/task.\n", (unsigned long) pid); 451 Prelease(ph); 452 return NULL; 453 } 454 455 closedir (dir); 456 #endif 457 return ph; 458 } |