changeset 11:c7690676c2a6

Bug 1633: Cannot attach HeapStats agent to OpenJDK7 in Fedora20 reviewed-by: ykubota
author Yasumasa Suenaga <suenaga.yasumasa@lab.ntt.co.jp>
date Thu, 09 Jan 2014 13:16:51 +0900
parents 4a902634e147
children 87dc27ccb8b0
files agent/ChangeLog agent/src/oopUtil.cpp agent/src/symbolFinder.cpp agent/src/symbolFinder.hpp
diffstat 4 files changed, 90 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/agent/ChangeLog	Mon Dec 16 10:35:34 2013 +0900
+++ b/agent/ChangeLog	Thu Jan 09 13:16:51 2014 +0900
@@ -1,3 +1,7 @@
+2014-01-09  Yasumasa Suenaga  <suenaga.yasumasa@lab.ntt.co.jp>
+
+	* Bug 1633: Cannot attach HeapStats agent to OpenJDK7 in Fedora20
+
 2013-12-16  Yasumasa Suenaga  <suenaga.yasumasa@lab.ntt.co.jp>
 
 	* Bug 1621: Incorrect hook point: G1GC after CR#6964458
--- a/agent/src/oopUtil.cpp	Mon Dec 16 10:35:34 2013 +0900
+++ b/agent/src/oopUtil.cpp	Thu Jan 09 13:16:51 2014 +0900
@@ -2743,7 +2743,7 @@
     try {
         /* Create symbol finder instance. */
         symFinder = new TSymbolFinder();
-        if (unlikely(!symFinder->loadLibrary(libPath))) {
+        if (unlikely(!symFinder->loadLibrary(libPath, "libjvm.so"))) {
             throw 1;
         }
         
--- a/agent/src/symbolFinder.cpp	Mon Dec 16 10:35:34 2013 +0900
+++ b/agent/src/symbolFinder.cpp	Thu Jan 09 13:16:51 2014 +0900
@@ -32,6 +32,7 @@
 #include <bfd.h>
 #include <errno.h>
 #include <sys/stat.h>
+#include <libgen.h>
 
 #include "symbolFinder.hpp"
 #include "util.hpp"
@@ -44,18 +45,25 @@
 /*!
  * \brief Create record stored library information.
  * \param libinfo [out] Record of library information.
- * \param libPath [in]  Target library path.
+ * \param libPath [in]  Part of target library path.
+ * \param libName [in]  Target library name.
  */
-inline void createLibInfo(TLibraryInfo *libinfo, char const* libPath) {
-    libinfo->libname_len = strlen(libPath);
-    libinfo->libname = (char *)malloc(libinfo->libname_len + 1);
-    
-    /* If failure allocate memory. */
-    if (unlikely(libinfo->libname == NULL)) {
-        return;
-    }
-    
-    strcpy(libinfo->libname, libPath);
+inline void createLibInfo(TLibraryInfo *libinfo,
+                                 const char* libPath, const char *libName){
+  libinfo->libpath_len = strlen(libPath);
+  libinfo->libpath = strdup(libPath);
+  if(unlikely(libinfo->libpath == NULL)){
+    return;
+  }
+
+  libinfo->libname = strdup(libName);
+  libinfo->libname_len = strlen(libName);
+  if(unlikely(libinfo->libname == NULL)){
+    free(libinfo->libpath);
+    libinfo->libpath = NULL;
+    return;
+  }
+
 }
 
 /*!
@@ -68,22 +76,27 @@
  */
 static int libraryCallback(struct dl_phdr_info *info, size_t size, void *data) {
     TLibraryInfo *libinfo = (TLibraryInfo *)data;
-    
-    /* If library is need. */
-    if (strncmp(info->dlpi_name, libinfo->libname, libinfo->libname_len) == 0) {
-        
-        /* Clean old string. */
-        free(libinfo->libname);
-        
-        /* Store library information. */
-        createLibInfo(libinfo, info->dlpi_name);
-        libinfo->baseaddr = info->dlpi_addr;
-        
-        /* Abort callback loop. */
-        return 1;
-    }
-    
-    return 0;
+
+  /*
+   * Get real path of library.
+   * "sun.boot.library.path" system property for libjvm.so will be set real path.
+   * See os::jvm_path() in hotspot/src/os/linux/vm/os_linux.cpp
+   */
+  char real_path[PATH_MAX];
+  realpath(info->dlpi_name, real_path);
+
+  /* If library is need. */
+  if((strncmp(real_path, libinfo->libpath, libinfo->libpath_len) == 0) &&
+     (strncmp(basename(real_path), libinfo->libname, libinfo->libname_len) == 0)){
+    /* Store library information. */
+    libinfo->realpath = strdup(real_path);
+    libinfo->baseaddr = info->dlpi_addr;
+
+    /* Abort callback loop. */
+    return 1;
+  }
+
+  return 0;
 }
 
 /*!
@@ -117,35 +130,45 @@
 /*!
  * \brief Load target libaray.
  * \param pathPattern [in] Pattern of target library path.
+ * \param libname     [in] Name of library.
  * \return Is success load library.<br>
  */
-bool TSymbolFinder::loadLibrary(const char *pathPattern) {
+bool TSymbolFinder::loadLibrary(const char *pathPattern, const char *libname){
     /* Sanity check. */
     if (unlikely(pathPattern == NULL)) {
-        PRINT_WARN_MSG("Failure allocate library path.");
+        PRINT_WARN_MSG("Library path is not set.");
         return false;
     }
-    
+
+    if (unlikely(libname == NULL)) {
+      PRINT_WARN_MSG("Library name is not set.");
+      return false;
+    }
+
     /* Initialize. */
-    createLibInfo(&targetLibInfo, pathPattern);
+    createLibInfo(&targetLibInfo, pathPattern, libname);
+    targetLibInfo.realpath = NULL;
     targetLibInfo.baseaddr = ((ptrdiff_t)0);
     
     /* If failure allocate memory. */
-    if (unlikely(targetLibInfo.libname == NULL)) {
-        PRINT_WARN_MSG("Failure allocate library path.");
-        return false;
+    if(unlikely(
+       (targetLibInfo.libpath == NULL) || (targetLibInfo.libname == NULL))){
+      PRINT_WARN_MSG("Cannot allocate memory for searching symbols.");
+      return false;
     }
     
     /* Search target library on memory. */
-    if (unlikely(dl_iterate_phdr(&libraryCallback, &targetLibInfo) == 0)) {
-        PRINT_WARN_MSG("Failure search library on memory.");
-        free(targetLibInfo.libname);
-        targetLibInfo.libname = NULL;
-        return false;
+    if(unlikely(dl_iterate_phdr(&libraryCallback, &targetLibInfo) == 0)){
+      PRINT_WARN_MSG_HEADER << "Cannot find library: " << libname << NEWLINE;
+      free(targetLibInfo.libname);
+      targetLibInfo.libname = NULL;
+      free(targetLibInfo.libpath);
+      targetLibInfo.libpath = NULL;
+      return false;
     }
     
     /* Load library with bfd record. */
-    loadLibraryInfo(targetLibInfo.libname, &libBfdInfo);
+    loadLibraryInfo(targetLibInfo.realpath, &libBfdInfo);
 
     /* If bfd record has the symbols, no need to search debuginfo */
     if (libBfdInfo.hasSymtab && libBfdInfo.staticSymCnt > 0 && libBfdInfo.dynSymCnt > 0) {
@@ -214,12 +237,16 @@
     /* If failure both load process. */
     if (unlikely(libBfdInfo.staticSymCnt == 0 && debugBfdInfo.staticSymCnt == 0
         && libBfdInfo.dynSymCnt == 0 && debugBfdInfo.dynSymCnt == 0)) {
-        
-        PRINT_WARN_MSG("Failure load information about library.");
-        free(targetLibInfo.libname);
-        targetLibInfo.libname = NULL;
-        return false;
+      PRINT_WARN_MSG("Cannot load library information.");
+      free(targetLibInfo.libname);
+      targetLibInfo.libname = NULL;
+      free(targetLibInfo.libpath);
+      targetLibInfo.libpath = NULL;
+      free(targetLibInfo.realpath);
+      targetLibInfo.realpath = NULL;
+      return false;
     }
+
     return true;
 }
 
@@ -384,7 +411,11 @@
     /* Cleanup. */
     free(targetLibInfo.libname);
     targetLibInfo.libname = NULL;
-    
+    free(targetLibInfo.libpath);
+    targetLibInfo.libpath = NULL;
+    free(targetLibInfo.realpath);
+    targetLibInfo.realpath = NULL;
+
     /* Deallocate and null-clear bfd object. */
     if (unlikely(libBfdInfo.bfdInfo != NULL)) {
         bfd_close(libBfdInfo.bfdInfo);
--- a/agent/src/symbolFinder.hpp	Mon Dec 16 10:35:34 2013 +0900
+++ b/agent/src/symbolFinder.hpp	Thu Jan 09 13:16:51 2014 +0900
@@ -47,9 +47,12 @@
  * \brief Data container of shared library name and loaded virtual address.
  */
 typedef struct{
-    char *libname;      /*!< Name of target library.          */
-    size_t libname_len; /*!< Length of library name.          */
-    ptrdiff_t baseaddr; /*!< Pointer of library base address. */
+  char *libname;      /*!< Name of target library.          */
+  size_t libname_len; /*!< Length of target library name.   */
+  char *libpath;      /*!< Part of library path.            */
+  size_t libpath_len; /*!< Length of library path.          */
+  char *realpath;     /*!< Real path of library.            */
+  ptrdiff_t baseaddr; /*!< Pointer of library base address. */
 } TLibraryInfo;
 
 /*!
@@ -95,9 +98,10 @@
         /*!
          * \brief Load target libaray.
          * \param pathPattern [in] Pattern of target library path.
+         * \param libname     [in] Name of library.
          * \return Is success load library.<br>
          */
-        virtual bool loadLibrary(const char *pathPattern);
+        virtual bool loadLibrary(const char *pathPattern, const char *libname);
         
         /*!
          * \brief Find symbol in target library.