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 }
|