2022-03-02 09:49:05 +08:00
|
|
|
From ed8ff7161f021b4a9cb5ec7c4c55c7b62a0ac389 Mon Sep 17 00:00:00 2001
|
|
|
|
|
From: d30023828 <douyiwang@huawei.com>
|
|
|
|
|
Date: Wed, 9 Feb 2022 18:32:05 +0800
|
|
|
|
|
Subject: [PATCH 3/8] 8268819: SA: Remove libthread_db dependency on Linux
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
.../agent/src/os/linux/LinuxDebuggerLocal.c | 3 +-
|
|
|
|
|
hotspot/agent/src/os/linux/Makefile | 6 +-
|
|
|
|
|
hotspot/agent/src/os/linux/libproc.h | 35 +--------
|
|
|
|
|
hotspot/agent/src/os/linux/libproc_impl.c | 76 +------------------
|
|
|
|
|
hotspot/agent/src/os/linux/libproc_impl.h | 8 +-
|
|
|
|
|
hotspot/agent/src/os/linux/proc_service.h | 12 +--
|
|
|
|
|
hotspot/agent/src/os/linux/ps_core.c | 6 +-
|
|
|
|
|
hotspot/agent/src/os/linux/ps_proc.c | 35 +++++++--
|
|
|
|
|
.../debugger/linux/LinuxDebuggerLocal.java | 2 +-
|
|
|
|
|
hotspot/make/linux/makefiles/saproc.make | 2 +-
|
|
|
|
|
10 files changed, 46 insertions(+), 139 deletions(-)
|
|
|
|
|
|
|
|
|
|
diff --git a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c
|
|
|
|
|
index d6a0c7d9a..a4c6f4057 100644
|
|
|
|
|
--- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c
|
|
|
|
|
+++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c
|
|
|
|
|
@@ -1,5 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
|
*
|
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
|
@@ -24,6 +24,7 @@
|
|
|
|
|
|
|
|
|
|
#include <jni.h>
|
|
|
|
|
#include "libproc.h"
|
|
|
|
|
+#include "proc_service.h"
|
|
|
|
|
|
|
|
|
|
#include <elf.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
diff --git a/hotspot/agent/src/os/linux/Makefile b/hotspot/agent/src/os/linux/Makefile
|
|
|
|
|
index c0b5c869c..957b4b555 100644
|
|
|
|
|
--- a/hotspot/agent/src/os/linux/Makefile
|
|
|
|
|
+++ b/hotspot/agent/src/os/linux/Makefile
|
|
|
|
|
@@ -38,8 +38,6 @@ INCLUDES = -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux
|
|
|
|
|
|
|
|
|
|
OBJS = $(SOURCES:%.c=$(ARCH)/%.o) $(ARCH)/sadis.o
|
|
|
|
|
|
|
|
|
|
-LIBS = -lthread_db
|
|
|
|
|
-
|
|
|
|
|
CFLAGS = -c -fPIC -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) -I$(ARCH)
|
|
|
|
|
|
|
|
|
|
LIBSA = $(ARCH)/libsaproc.so
|
|
|
|
|
@@ -81,13 +79,13 @@ LDFLAGS_NO_EXEC_STACK="-Wl,-z,noexecstack"
|
|
|
|
|
LFLAGS_LIBSA += $(LDFLAGS_NO_EXEC_STACK)
|
|
|
|
|
|
|
|
|
|
$(LIBSA): $(ARCH) $(OBJS) mapfile
|
|
|
|
|
- $(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(OBJS) $(LIBS)
|
|
|
|
|
+ $(GCC) -shared $(LFLAGS_LIBSA) -o $(LIBSA) $(OBJS)
|
|
|
|
|
|
|
|
|
|
test.o: test.c
|
|
|
|
|
$(GCC) -c -o test.o -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) test.c
|
|
|
|
|
|
|
|
|
|
test: test.o
|
|
|
|
|
- $(GCC) -o test test.o -L$(ARCH) -lsaproc $(LIBS)
|
|
|
|
|
+ $(GCC) -o test test.o -L$(ARCH) -lsaproc
|
|
|
|
|
|
|
|
|
|
clean:
|
|
|
|
|
rm -fr $(ARCH)
|
|
|
|
|
diff --git a/hotspot/agent/src/os/linux/libproc.h b/hotspot/agent/src/os/linux/libproc.h
|
|
|
|
|
index 6b6e41cab..36e82d207 100644
|
|
|
|
|
--- a/hotspot/agent/src/os/linux/libproc.h
|
|
|
|
|
+++ b/hotspot/agent/src/os/linux/libproc.h
|
|
|
|
|
@@ -1,5 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
|
*
|
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
|
@@ -28,49 +28,18 @@
|
|
|
|
|
#include <jni.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
-#include "proc_service.h"
|
|
|
|
|
|
|
|
|
|
#ifdef ALT_SASRCDIR
|
|
|
|
|
#include "libproc_md.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
+#include <sys/procfs.h>
|
|
|
|
|
#include <sys/ptrace.h>
|
|
|
|
|
|
|
|
|
|
#if defined(aarch64)
|
|
|
|
|
#include "asm/ptrace.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
-/************************************************************************************
|
|
|
|
|
-
|
|
|
|
|
-0. This is very minimal subset of Solaris libproc just enough for current application.
|
|
|
|
|
-Please note that the bulk of the functionality is from proc_service interface. This
|
|
|
|
|
-adds Pgrab__ and some missing stuff. We hide the difference b/w live process and core
|
|
|
|
|
-file by this interface.
|
|
|
|
|
-
|
|
|
|
|
-1. pthread_id unique in both NPTL & LinuxThreads. We store this in
|
|
|
|
|
-OSThread::_pthread_id in JVM code.
|
|
|
|
|
-
|
|
|
|
|
-2. All threads see the same pid when they call getpid() under NPTL.
|
|
|
|
|
-Threads receive different pid under LinuxThreads. We used to save the result of
|
|
|
|
|
-::getpid() call in OSThread::_thread_id. This way uniqueness of OSThread::_thread_id
|
|
|
|
|
-was lost under NPTL. Now, we store the result of ::gettid() call in
|
|
|
|
|
-OSThread::_thread_id. Because gettid returns actual pid of thread (lwp id), this is
|
|
|
|
|
-unique again. We therefore use OSThread::_thread_id as unique identifier.
|
|
|
|
|
-
|
|
|
|
|
-3. There is a unique LWP id under both thread libraries. libthread_db maps pthread_id
|
|
|
|
|
-to its underlying lwp_id under both the thread libraries. thread_info.lwp_id stores
|
|
|
|
|
-lwp_id of the thread. The lwp id is nothing but the actual pid of clone'd processes. But
|
|
|
|
|
-unfortunately libthread_db does not work very well for core dumps. So, we get pthread_id
|
|
|
|
|
-only for processes. For core dumps, we don't use libthread_db at all (like gdb).
|
|
|
|
|
-
|
|
|
|
|
-4. ptrace operates on this LWP id under both the thread libraries. When we say 'pid' for
|
|
|
|
|
-ptrace call, we refer to lwp_id of the thread.
|
|
|
|
|
-
|
|
|
|
|
-5. for core file, we parse ELF files and read data from them. For processes we use
|
|
|
|
|
-combination of ptrace and /proc calls.
|
|
|
|
|
-
|
|
|
|
|
-*************************************************************************************/
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
#if defined(sparc) || defined(sparcv9) || defined(ppc64)
|
|
|
|
|
#include <asm/ptrace.h>
|
|
|
|
|
diff --git a/hotspot/agent/src/os/linux/libproc_impl.c b/hotspot/agent/src/os/linux/libproc_impl.c
|
|
|
|
|
index 73a15ce35..cf5bd030f 100644
|
|
|
|
|
--- a/hotspot/agent/src/os/linux/libproc_impl.c
|
|
|
|
|
+++ b/hotspot/agent/src/os/linux/libproc_impl.c
|
|
|
|
|
@@ -26,8 +26,9 @@
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
-#include <thread_db.h>
|
|
|
|
|
+#include <sys/procfs.h>
|
|
|
|
|
#include "libproc_impl.h"
|
|
|
|
|
+#include "proc_service.h"
|
|
|
|
|
|
|
|
|
|
#define SA_ALTROOT "SA_ALTROOT"
|
|
|
|
|
|
|
|
|
|
@@ -105,13 +106,6 @@ bool is_debug() {
|
|
|
|
|
bool init_libproc(bool debug) {
|
|
|
|
|
// init debug mode
|
|
|
|
|
_libsaproc_debug = debug;
|
|
|
|
|
-
|
|
|
|
|
- // initialize the thread_db library
|
|
|
|
|
- if (td_init() != TD_OK) {
|
|
|
|
|
- print_debug("libthread_db's td_init failed\n");
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -243,7 +237,7 @@ const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* p
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add a thread to ps_prochandle
|
|
|
|
|
-thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
|
|
|
|
|
+thread_info* add_thread_info(struct ps_prochandle* ph, lwpid_t lwp_id) {
|
|
|
|
|
thread_info* newthr;
|
|
|
|
|
if ( (newthr = (thread_info*) calloc(1, sizeof(thread_info))) == NULL) {
|
|
|
|
|
print_debug("can't allocate memory for thread_info\n");
|
|
|
|
|
@@ -251,7 +245,6 @@ thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwp
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// initialize thread info
|
|
|
|
|
- newthr->pthread_id = pthread_id;
|
|
|
|
|
newthr->lwp_id = lwp_id;
|
|
|
|
|
|
|
|
|
|
// add new thread to the list
|
|
|
|
|
@@ -282,64 +275,6 @@ void delete_thread_info(struct ps_prochandle* ph, thread_info* thr_to_be_removed
|
|
|
|
|
free(current_thr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-// struct used for client data from thread_db callback
|
|
|
|
|
-struct thread_db_client_data {
|
|
|
|
|
- struct ps_prochandle* ph;
|
|
|
|
|
- thread_info_callback callback;
|
|
|
|
|
-};
|
|
|
|
|
-
|
|
|
|
|
-// callback function for libthread_db
|
|
|
|
|
-static int thread_db_callback(const td_thrhandle_t *th_p, void *data) {
|
|
|
|
|
- struct thread_db_client_data* ptr = (struct thread_db_client_data*) data;
|
|
|
|
|
- td_thrinfo_t ti;
|
|
|
|
|
- td_err_e err;
|
|
|
|
|
-
|
|
|
|
|
- memset(&ti, 0, sizeof(ti));
|
|
|
|
|
- err = td_thr_get_info(th_p, &ti);
|
|
|
|
|
- if (err != TD_OK) {
|
|
|
|
|
- print_debug("libthread_db : td_thr_get_info failed, can't get thread info\n");
|
|
|
|
|
- return err;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- print_debug("thread_db : pthread %d (lwp %d)\n", ti.ti_tid, ti.ti_lid);
|
|
|
|
|
-
|
|
|
|
|
- if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) {
|
|
|
|
|
- print_debug("Skipping pthread %d (lwp %d)\n", ti.ti_tid, ti.ti_lid);
|
|
|
|
|
- return TD_OK;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (ptr->callback(ptr->ph, ti.ti_tid, ti.ti_lid) != true)
|
|
|
|
|
- return TD_ERR;
|
|
|
|
|
-
|
|
|
|
|
- return TD_OK;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// read thread_info using libthread_db
|
|
|
|
|
-bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb) {
|
|
|
|
|
- struct thread_db_client_data mydata;
|
|
|
|
|
- td_thragent_t* thread_agent = NULL;
|
|
|
|
|
- if (td_ta_new(ph, &thread_agent) != TD_OK) {
|
|
|
|
|
- print_debug("can't create libthread_db agent\n");
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- mydata.ph = ph;
|
|
|
|
|
- mydata.callback = cb;
|
|
|
|
|
-
|
|
|
|
|
- // we use libthread_db iterator to iterate thru list of threads.
|
|
|
|
|
- if (td_ta_thr_iter(thread_agent, thread_db_callback, &mydata,
|
|
|
|
|
- TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
|
|
|
|
|
- TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS) != TD_OK) {
|
|
|
|
|
- td_ta_delete(thread_agent);
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // delete thread agent
|
|
|
|
|
- td_ta_delete(thread_agent);
|
|
|
|
|
- return true;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
// get number of threads
|
|
|
|
|
int get_num_threads(struct ps_prochandle* ph) {
|
|
|
|
|
return ph->num_threads;
|
|
|
|
|
@@ -463,8 +398,3 @@ ps_err_e ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset)
|
|
|
|
|
return PS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-// new libthread_db of NPTL seem to require this symbol
|
|
|
|
|
-ps_err_e ps_get_thread_area() {
|
|
|
|
|
- print_debug("ps_get_thread_area not implemented\n");
|
|
|
|
|
- return PS_OK;
|
|
|
|
|
-}
|
|
|
|
|
diff --git a/hotspot/agent/src/os/linux/libproc_impl.h b/hotspot/agent/src/os/linux/libproc_impl.h
|
|
|
|
|
index 1d25a0922..8546bbf5a 100644
|
|
|
|
|
--- a/hotspot/agent/src/os/linux/libproc_impl.h
|
|
|
|
|
+++ b/hotspot/agent/src/os/linux/libproc_impl.h
|
|
|
|
|
@@ -46,7 +46,6 @@ typedef struct lib_info {
|
|
|
|
|
// list of threads
|
|
|
|
|
typedef struct thread_info {
|
|
|
|
|
lwpid_t lwp_id;
|
|
|
|
|
- pthread_t pthread_id; // not used cores, always -1
|
|
|
|
|
struct user_regs_struct regs; // not for process, core uses for caching regset
|
|
|
|
|
struct thread_info* next;
|
|
|
|
|
} thread_info;
|
|
|
|
|
@@ -108,11 +107,6 @@ void print_debug(const char* format,...);
|
|
|
|
|
void print_error(const char* format,...);
|
|
|
|
|
bool is_debug();
|
|
|
|
|
|
|
|
|
|
-typedef bool (*thread_info_callback)(struct ps_prochandle* ph, pthread_t pid, lwpid_t lwpid);
|
|
|
|
|
-
|
|
|
|
|
-// reads thread info using libthread_db and calls above callback for each thread
|
|
|
|
|
-bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb);
|
|
|
|
|
-
|
|
|
|
|
// deletes a thread from the thread list
|
|
|
|
|
void delete_thread_info(struct ps_prochandle* ph, thread_info* thr);
|
|
|
|
|
|
|
|
|
|
@@ -124,7 +118,7 @@ lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd,
|
|
|
|
|
uintptr_t base);
|
|
|
|
|
|
|
|
|
|
// adds a new thread to threads list, returns NULL on failure
|
|
|
|
|
-thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id);
|
|
|
|
|
+thread_info* add_thread_info(struct ps_prochandle* ph, lwpid_t lwp_id);
|
|
|
|
|
|
|
|
|
|
// a test for ELF signature without using libelf
|
|
|
|
|
bool is_elf_file(int fd);
|
|
|
|
|
diff --git a/hotspot/agent/src/os/linux/proc_service.h b/hotspot/agent/src/os/linux/proc_service.h
|
|
|
|
|
index 802e5b0bb..a8e0c2a5c 100644
|
|
|
|
|
--- a/hotspot/agent/src/os/linux/proc_service.h
|
|
|
|
|
+++ b/hotspot/agent/src/os/linux/proc_service.h
|
|
|
|
|
@@ -1,5 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
+ * Copyright (c) 2003,2019, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
|
*
|
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
|
@@ -26,11 +26,10 @@
|
|
|
|
|
#define _PROC_SERVICE_H_
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
-#include <thread_db.h>
|
|
|
|
|
+#include <sys/procfs.h>
|
|
|
|
|
+
|
|
|
|
|
+#include "libproc.h"
|
|
|
|
|
|
|
|
|
|
-// Linux does not have the proc service library, though it does provide the
|
|
|
|
|
-// thread_db library which can be used to manipulate threads without having
|
|
|
|
|
-// to know the details of LinuxThreads or NPTL
|
|
|
|
|
|
|
|
|
|
// copied from Solaris "proc_service.h"
|
|
|
|
|
typedef enum {
|
|
|
|
|
@@ -70,7 +69,4 @@ ps_err_e ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lid, prfpregset_t *
|
|
|
|
|
|
|
|
|
|
ps_err_e ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset);
|
|
|
|
|
|
|
|
|
|
-// new libthread_db of NPTL seem to require this symbol
|
|
|
|
|
-ps_err_e ps_get_thread_area();
|
|
|
|
|
-
|
|
|
|
|
#endif /* _PROC_SERVICE_H_ */
|
|
|
|
|
diff --git a/hotspot/agent/src/os/linux/ps_core.c b/hotspot/agent/src/os/linux/ps_core.c
|
2022-07-22 15:27:58 +08:00
|
|
|
index 6fb8c940..5728bcc4 100644
|
2022-03-02 09:49:05 +08:00
|
|
|
--- a/hotspot/agent/src/os/linux/ps_core.c
|
|
|
|
|
+++ b/hotspot/agent/src/os/linux/ps_core.c
|
|
|
|
|
@@ -31,6 +31,7 @@
|
|
|
|
|
#include <elf.h>
|
|
|
|
|
#include <link.h>
|
|
|
|
|
#include "libproc_impl.h"
|
|
|
|
|
+#include "proc_service.h"
|
|
|
|
|
#include "salibelf.h"
|
2022-07-22 15:27:58 +08:00
|
|
|
|
2022-03-02 09:49:05 +08:00
|
|
|
// This file has the libproc implementation to read core files.
|
|
|
|
|
@@ -546,8 +547,7 @@ static bool core_handle_prstatus(struct ps_prochandle* ph, const char* buf, size
|
|
|
|
|
prstatus_t* prstat = (prstatus_t*) buf;
|
|
|
|
|
thread_info* newthr;
|
|
|
|
|
print_debug("got integer regset for lwp %d\n", prstat->pr_pid);
|
|
|
|
|
- // we set pthread_t to -1 for core dump
|
|
|
|
|
- if((newthr = add_thread_info(ph, (pthread_t) -1, prstat->pr_pid)) == NULL)
|
2022-07-22 15:27:58 +08:00
|
|
|
+ if((newthr = add_thread_info(ph, prstat->pr_pid)) == NULL)
|
2022-03-02 09:49:05 +08:00
|
|
|
return false;
|
2022-07-22 15:27:58 +08:00
|
|
|
|
2022-03-02 09:49:05 +08:00
|
|
|
// copy regs
|
|
|
|
|
diff --git a/hotspot/agent/src/os/linux/ps_proc.c b/hotspot/agent/src/os/linux/ps_proc.c
|
|
|
|
|
index c4d6a9ecc..748cc1397 100644
|
|
|
|
|
--- a/hotspot/agent/src/os/linux/ps_proc.c
|
|
|
|
|
+++ b/hotspot/agent/src/os/linux/ps_proc.c
|
|
|
|
|
@@ -1,5 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
|
*
|
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
|
@@ -28,6 +28,7 @@
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <elf.h>
|
|
|
|
|
+#include <dirent.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/wait.h>
|
|
|
|
|
@@ -338,11 +339,6 @@ static char * fgets_no_cr(char * buf, int n, FILE *fp)
|
|
|
|
|
return rslt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-// callback for read_thread_info
|
|
|
|
|
-static bool add_new_thread(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
|
|
|
|
|
- return add_thread_info(ph, pthread_id, lwp_id) != NULL;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
static bool read_lib_info(struct ps_prochandle* ph) {
|
|
|
|
|
char fname[32];
|
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
|
@@ -462,6 +458,7 @@ struct ps_prochandle* Pgrab(pid_t pid, char* err_buf, size_t err_buf_len) {
|
|
|
|
|
|
|
|
|
|
// initialize ps_prochandle
|
|
|
|
|
ph->pid = pid;
|
|
|
|
|
+ add_thread_info(ph, ph->pid);
|
|
|
|
|
|
|
|
|
|
// initialize vtable
|
|
|
|
|
ph->ops = &process_ops;
|
|
|
|
|
@@ -471,8 +468,30 @@ struct ps_prochandle* Pgrab(pid_t pid, char* err_buf, size_t err_buf_len) {
|
|
|
|
|
// the list of threads within the same process.
|
|
|
|
|
read_lib_info(ph);
|
|
|
|
|
|
|
|
|
|
- // read thread info
|
|
|
|
|
- read_thread_info(ph, add_new_thread);
|
|
|
|
|
+ /*
|
|
|
|
|
+ * Read thread info.
|
|
|
|
|
+ * SA scans all tasks in /proc/<PID>/task to read all threads info.
|
|
|
|
|
+ */
|
|
|
|
|
+ char taskpath[PATH_MAX];
|
|
|
|
|
+ DIR *dirp;
|
|
|
|
|
+ struct dirent *entry;
|
|
|
|
|
+
|
|
|
|
|
+ snprintf(taskpath, PATH_MAX, "/proc/%d/task", ph->pid);
|
|
|
|
|
+ dirp = opendir(taskpath);
|
|
|
|
|
+ int lwp_id;
|
|
|
|
|
+ while ((entry = readdir(dirp)) != NULL) {
|
|
|
|
|
+ if (*entry->d_name == '.') {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ lwp_id = atoi(entry->d_name);
|
|
|
|
|
+ if (lwp_id == ph->pid) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!process_doesnt_exist(lwp_id)) {
|
|
|
|
|
+ add_thread_info(ph, lwp_id);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ closedir(dirp);
|
|
|
|
|
|
|
|
|
|
// attach to the threads
|
|
|
|
|
thr = ph->threads;
|
|
|
|
|
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java
|
|
|
|
|
index f282a228d..7a28506b8 100644
|
|
|
|
|
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java
|
|
|
|
|
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java
|
|
|
|
|
@@ -1,5 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
|
*
|
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
|
diff --git a/hotspot/make/linux/makefiles/saproc.make b/hotspot/make/linux/makefiles/saproc.make
|
|
|
|
|
index 258585366..d9b1f14f4 100644
|
|
|
|
|
--- a/hotspot/make/linux/makefiles/saproc.make
|
|
|
|
|
+++ b/hotspot/make/linux/makefiles/saproc.make
|
|
|
|
|
@@ -108,7 +108,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
|
|
|
|
|
$(SA_OPT_FLAGS) \
|
|
|
|
|
$(EXTRA_CFLAGS) \
|
|
|
|
|
-o $@ \
|
|
|
|
|
- -lthread_db -ldl
|
|
|
|
|
+ -ldl
|
|
|
|
|
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
|
|
|
|
ifneq ($(STRIP_POLICY),no_strip)
|
|
|
|
|
$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO)
|
|
|
|
|
--
|
|
|
|
|
2.22.0
|
|
|
|
|
|