From 38daaa32f8ba6570b566a6fad3a1fa8d99c22c90 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Thu, 29 Jan 2026 10:21:47 +0900 Subject: [PATCH] Add new function to handle vDSO --- .../linux/native/libsaproc/ps_core.c | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c b/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c index fbf09ecf840..ade0eafdcaa 100644 --- a/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c +++ b/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c @@ -602,6 +602,38 @@ static uintptr_t calc_prelinked_load_address(struct ps_prochandle* ph, int lib_f return load_addr; } +// Override vDSO path to kernel directory (/lib/modules//vdso) if possible. +// Then lib_name would be overwritten that path. +// Otherwise copy vDSO memory in coredump to temporal memory generated by memfd_create(). +// Returns FD for vDSO (should be closed by caller). +static int handle_vdso(struct ps_prochandle* ph, char* lib_name, size_t lib_name_len) { + int lib_fd; + struct utsname uts; + uname(&uts); + + // Check vDSO binary first (for referring debuginfo if possible). + char *vdso_path = (char*)malloc(lib_name_len); + snprintf(vdso_path, lib_name_len, "/lib/modules/%s/vdso/vdso64.so", uts.release); + if (access(vdso_path, F_OK) == 0) { + print_debug("replace vDSO: %s -> %s\n", lib_name, vdso_path); + strncpy(lib_name, vdso_path, lib_name_len); + lib_fd = pathmap_open(lib_name); + } else { + // Copy vDSO memory segment from core to temporal memory + // if vDSO binary is not available. + lib_fd = memfd_create("[vdso] in core", 0); + off64_t ofs = ph->core->vdso_offset; + if (sendfile64(lib_fd, ph->core->core_fd, &ofs, ph->core->vdso_size) == -1) { + print_debug("can't copy vDSO (%d)\n", errno); + close(lib_fd); + lib_fd = -1; + } + } + + free(vdso_path); + return lib_fd; +} + // read shared library info from runtime linker's data structures. // This work is done by librtlb_db in Solaris static bool read_shared_lib_info(struct ps_prochandle* ph) { @@ -699,27 +731,7 @@ static bool read_shared_lib_info(struct ps_prochandle* ph) { if (lib_name[0] != '\0') { // ignore empty lib names if (strcmp("linux-vdso.so.1", lib_name) == 0 || strcmp("linux-vdso64.so.1", lib_name) == 0) { - struct utsname uts; - uname(&uts); - - // Check vDSO binary first (for referring debuginfo if possible). - char vdso_path[PATH_MAX]; - snprintf(vdso_path, sizeof(vdso_path), "/lib/modules/%s/vdso/vdso64.so", uts.release); - if (access(vdso_path, F_OK) == 0) { - print_debug("replace vDSO: %s -> %s\n", lib_name, vdso_path); - strcpy(lib_name, vdso_path); - lib_fd = pathmap_open(lib_name); - } else { - // Copy vDSO memory segment from core to temporal memory - // if vDSO binary is not available. - lib_fd = memfd_create("[vdso] in core", 0); - off64_t ofs = ph->core->vdso_offset; - if (sendfile64(lib_fd, ph->core->core_fd, &ofs, ph->core->vdso_size) == -1) { - print_debug("can't copy vDSO (%d)\n", errno); - close(lib_fd); - lib_fd = -1; - } - } + lib_fd = handle_vdso(ph, lib_name, sizeof(lib_name)); } else { lib_fd = pathmap_open(lib_name); }