changeset 29:bbf8065fcd37

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:46 +0900
parents 0a4a349799b0
children 57fd757ef0e2
files agent/ChangeLog agent/src/oopUtil.cpp agent/src/symbolFinder.cpp agent/src/symbolFinder.hpp
diffstat 4 files changed, 68 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/agent/ChangeLog	Thu Nov 21 15:21:34 2013 +0900
+++ b/agent/ChangeLog	Thu Jan 09 13:16:46 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-11-21  Yasumasa Suenaga  <suenaga.yasumasa@lab.ntt.co.jp>
 
 	* Bug 1593: HeapStats agent handles concurrent mode failure incorrectly.
--- a/agent/src/oopUtil.cpp	Thu Nov 21 15:21:34 2013 +0900
+++ b/agent/src/oopUtil.cpp	Thu Jan 09 13:16:46 2014 +0900
@@ -2191,7 +2191,7 @@
   try{
     /* Create symbol finder instance. */
     symFinder = new TSymbolFinder();
-    if(unlikely(!symFinder->loadLibrary(libPath))){
+    if(unlikely(!symFinder->loadLibrary(libPath, "libjvm.so"))){
       throw 0;
     }
     
--- a/agent/src/symbolFinder.cpp	Thu Nov 21 15:21:34 2013 +0900
+++ b/agent/src/symbolFinder.cpp	Thu Jan 09 13:16:46 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)) {
+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;
   }
-  
-  strcpy(libinfo->libname, libPath);
+
+  libinfo->libname = strdup(libName);
+  libinfo->libname_len = strlen(libName);
+  if(unlikely(libinfo->libname == NULL)){
+    free(libinfo->libpath);
+    libinfo->libpath = NULL;
+    return;
+  }
+
 }
 
 /*!
@@ -68,15 +76,20 @@
  */
 static int libraryCallback(struct dl_phdr_info *info, size_t size, void *data) {
   TLibraryInfo *libinfo = (TLibraryInfo *)data;
+
+  /* 
+   * 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(info->dlpi_name, libinfo->libname, libinfo->libname_len) == 0) {
-    
-    /* Clean old string. */
-    free(libinfo->libname);
-    
+  if((strncmp(real_path, libinfo->libpath, libinfo->libpath_len) == 0) &&
+     (strncmp(basename(real_path), libinfo->libname, libinfo->libname_len) == 0)){ 
     /* Store library information. */
-    createLibInfo(libinfo, info->dlpi_name);
+    libinfo->realpath = strdup(real_path);
     libinfo->baseaddr = info->dlpi_addr;
     
     /* Abort callback loop. */
@@ -113,6 +126,10 @@
   /* Cleanup. */
   free(targetLibInfo.libname);
   targetLibInfo.libname = NULL;
+  free(targetLibInfo.libpath);
+  targetLibInfo.libpath = NULL;
+  free(targetLibInfo.realpath);
+  targetLibInfo.realpath = NULL;
   
   if (likely(libBfdInfo.bfdInfo != NULL)) {
     bfd_close(libBfdInfo.bfdInfo);
@@ -143,34 +160,46 @@
 /*!
  * \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.");
+  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.");
+    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) {
@@ -239,9 +268,13 @@
   /* 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.");
+    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;
   }
   
--- a/agent/src/symbolFinder.hpp	Thu Nov 21 15:21:34 2013 +0900
+++ b/agent/src/symbolFinder.hpp	Thu Jan 09 13:16:46 2014 +0900
@@ -46,7 +46,10 @@
  */
 typedef struct{
   char *libname;      /*!< Name of target library.          */
-  size_t libname_len; /*!< Length of library name.          */
+  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;
 
@@ -93,9 +96,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.