< prev index next >

src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c

Print this page


   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 }


< prev index next >