< prev index next >

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

Print this page




  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 #include "libproc_impl.h"
  36 
  37 #if defined(x86_64) && !defined(amd64)
  38 #define amd64 1
  39 #endif
  40 
  41 #ifndef __WALL
  42 #define __WALL          0x40000000  // Copied from /usr/include/linux/wait.h
  43 #endif
  44 
  45 // This file has the libproc implementation specific to live process
  46 // For core files, refer to ps_core.c
  47 
  48 static inline uintptr_t align(uintptr_t ptr, size_t size) {
  49   return (ptr & ~(size - 1));
  50 }


 357   thread_info* thr = ph->threads;
 358   while (thr) {
 359      ptrace_detach(thr->lwp_id);
 360      thr = thr->next;
 361   }
 362 }
 363 
 364 static void process_cleanup(struct ps_prochandle* ph) {
 365   detach_all_pids(ph);
 366 }
 367 
 368 static ps_prochandle_ops process_ops = {
 369   .release=  process_cleanup,
 370   .p_pread=  process_read_data,
 371   .p_pwrite= process_write_data,
 372   .get_lwp_regs= process_get_lwp_regs
 373 };
 374 
 375 // attach to the process. One and only one exposed stuff
 376 JNIEXPORT struct ps_prochandle* JNICALL
 377 Pgrab(pid_t pid, char* err_buf, size_t err_buf_len) {
 378   struct ps_prochandle* ph = NULL;
 379   thread_info* thr = NULL;
 380 
 381   if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
 382      snprintf(err_buf, err_buf_len, "can't allocate memory for ps_prochandle");
 383      print_debug("%s\n", err_buf);
 384      return NULL;
 385   }
 386 
 387   if (ptrace_attach(pid, err_buf, err_buf_len) != true) {
 388      free(ph);
 389      return NULL;
 390   }
 391 
 392   // initialize ps_prochandle
 393   ph->pid = pid;
 394 
 395   // initialize vtable
 396   ph->ops = &process_ops;
 397 
 398   // read library info and symbol tables, must do this before attaching threads,
 399   // as the symbols in the pthread library will be used to figure out
 400   // the list of threads within the same process.
 401   read_lib_info(ph);
 402 
 403   // read thread info
























 404   read_thread_info(ph, add_new_thread);

 405 
 406   // attach to the threads
 407   thr = ph->threads;
 408   while (thr) {
 409      // don't attach to the main thread again
 410     if (ph->pid != thr->lwp_id && ptrace_attach(thr->lwp_id, err_buf, err_buf_len) != true) {
 411         // even if one attach fails, we get return NULL
 412         Prelease(ph);
 413         return NULL;
 414      }
 415      thr = thr->next;
 416   }
 417   return ph;
 418 }


  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 <dirent.h>
  32 #include <sys/types.h>
  33 #include <sys/wait.h>
  34 #include <sys/ptrace.h>
  35 #include <sys/uio.h>
  36 #include "libproc_impl.h"
  37 
  38 #if defined(x86_64) && !defined(amd64)
  39 #define amd64 1
  40 #endif
  41 
  42 #ifndef __WALL
  43 #define __WALL          0x40000000  // Copied from /usr/include/linux/wait.h
  44 #endif
  45 
  46 // This file has the libproc implementation specific to live process
  47 // For core files, refer to ps_core.c
  48 
  49 static inline uintptr_t align(uintptr_t ptr, size_t size) {
  50   return (ptr & ~(size - 1));
  51 }


 358   thread_info* thr = ph->threads;
 359   while (thr) {
 360      ptrace_detach(thr->lwp_id);
 361      thr = thr->next;
 362   }
 363 }
 364 
 365 static void process_cleanup(struct ps_prochandle* ph) {
 366   detach_all_pids(ph);
 367 }
 368 
 369 static ps_prochandle_ops process_ops = {
 370   .release=  process_cleanup,
 371   .p_pread=  process_read_data,
 372   .p_pwrite= process_write_data,
 373   .get_lwp_regs= process_get_lwp_regs
 374 };
 375 
 376 // attach to the process. One and only one exposed stuff
 377 JNIEXPORT struct ps_prochandle* JNICALL
 378 Pgrab(pid_t pid, char* err_buf, size_t err_buf_len, bool is_in_container) {
 379   struct ps_prochandle* ph = NULL;
 380   thread_info* thr = NULL;
 381 
 382   if ( (ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle))) == NULL) {
 383      snprintf(err_buf, err_buf_len, "can't allocate memory for ps_prochandle");
 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   if (is_in_container) {
 406     /*
 407      * If the process is running in the container, SA scans all tasks in
 408      * /proc/<PID>/task to read all threads info.
 409      */
 410     char taskpath[PATH_MAX];
 411     DIR *dirp;
 412     struct dirent *entry;
 413 
 414     snprintf(taskpath, PATH_MAX, "/proc/%d/task", ph->pid);
 415     dirp = opendir(taskpath);
 416     int lwp_id;
 417     while ((entry = readdir(dirp)) != NULL) {
 418       if (*entry->d_name == '.') {
 419         continue;
 420       }
 421       lwp_id = atoi(entry->d_name);
 422       if (lwp_id == ph->pid) {
 423         continue;
 424       }
 425       add_new_thread(ph, -1, lwp_id);
 426     }
 427     closedir(dirp);
 428   } else {
 429     read_thread_info(ph, add_new_thread);
 430   }
 431 
 432   // attach to the threads
 433   thr = ph->threads;
 434   while (thr) {
 435      // don't attach to the main thread again
 436     if (ph->pid != thr->lwp_id && ptrace_attach(thr->lwp_id, err_buf, err_buf_len) != true) {
 437         // even if one attach fails, we get return NULL
 438         Prelease(ph);
 439         return NULL;
 440      }
 441      thr = thr->next;
 442   }
 443   return ph;
 444 }
< prev index next >