changeset 13:1d573d30fe94

Bug 1485: Change the method of finding debuginfo files. reviewed-by: ykubota
author Yasumasa Suenaga <suenaga.yasumasa@lab.ntt.co.jp>
date Mon, 24 Jun 2013 11:42:50 +0900
parents 692643c03a50
children 27a3ec638eaa
files agent/ChangeLog agent/src/snapShotMain.cpp agent/src/symbolFinder.cpp agent/src/symbolFinder.hpp agent/src/util.cpp agent/src/util.hpp
diffstat 6 files changed, 93 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/agent/ChangeLog	Tue Jun 18 13:07:18 2013 +0900
+++ b/agent/ChangeLog	Mon Jun 24 11:42:50 2013 +0900
@@ -1,3 +1,7 @@
+2013-06-24  Yasumasa Suenaga  <suenaga.yasumasa@lab.ntt.co.jp>
+
+	* Bug 1485: Change the method of finding debuginfo files.
+
 2013-06-18  Yasumasa Suenaga  <suenaga.yasumasa@lab.ntt.co.jp>
 
 	* Bug 1472: Reduce re-run "configure" caused by automake version
--- a/agent/src/snapShotMain.cpp	Tue Jun 18 13:07:18 2013 +0900
+++ b/agent/src/snapShotMain.cpp	Mon Jun 24 11:42:50 2013 +0900
@@ -671,7 +671,7 @@
   
   /* Initialize oop util. */
   if (unlikely(!oopUtilInitialize(*jvmti))) {
-    PRINT_CRIT_MSG("Getting low level infomation failed!");
+    PRINT_CRIT_MSG("Getting low level information failed!");
     return GET_LOW_LEVEL_INFO_FAILED;
   }
   
--- a/agent/src/symbolFinder.cpp	Tue Jun 18 13:07:18 2013 +0900
+++ b/agent/src/symbolFinder.cpp	Mon Jun 24 11:42:50 2013 +0900
@@ -171,18 +171,62 @@
   /* Load library with bfd record. */
   loadLibraryInfo(targetLibInfo.libname, &libBfdInfo);
   
-  /* Create debuginfo path. */
-  char dbgInfoPath[PATH_MAX + 1] = {0};
-  snprintf(dbgInfoPath, PATH_MAX, DEBUGINFO_DIR "%s" DEBUGINFO_SUFFIX,
-    targetLibInfo.libname);
-  
-  /* Load library's debuginfo with bfd record. */
-  loadLibraryInfo(dbgInfoPath, &debugBfdInfo);
-  
+  char dbgInfoPath[PATH_MAX];
+  dbgInfoPath[0] = '\0';
+
+  /* Try to get debuginfo path from .note.gnu.build-id */
+  asection *buid_id_section = bfd_get_section_by_name(
+                                       libBfdInfo.bfdInfo, ".note.gnu.build-id");
+  if(buid_id_section != NULL){
+    TBuildIdInfo *buildID;
+
+    if(bfd_malloc_and_get_section(libBfdInfo.bfdInfo,
+                                       buid_id_section, (bfd_byte **)&buildID)){
+      sprintf(dbgInfoPath, DEBUGINFO_DIR "/.build-id/%02hhx/",
+                                  *(&(buildID->contents) + buildID->name_size));
+
+      for(unsigned int Cnt = buildID->name_size + 1;
+             Cnt < buildID->name_size + buildID->hash_size; Cnt++){
+        char digitChars[3];
+        sprintf(digitChars, "%02hhx", *(&(buildID->contents) + Cnt));
+        strcat(dbgInfoPath, digitChars);
+      }
+
+      strcat(dbgInfoPath, DEBUGINFO_SUFFIX);
+    }
+
+    if(buildID != NULL){
+      free(buildID);
+    }
+
+  }
+
+  if(dbgInfoPath[0] == '\0'){
+    /* Try to get debuginfo path from .gnu_debuglink */
+    char *buf = bfd_follow_gnu_debuglink(libBfdInfo.bfdInfo, DEBUGINFO_DIR);
+
+    if(buf != NULL){
+      strcpy(dbgInfoPath, buf);
+      free(buf);
+    }
+
+  }
+
+  if(dbgInfoPath[0] != '\0'){
+    /* Load library's debuginfo with bfd record. */
+    PRINT_DEBUG_MSG_HEADER << "Try to read debuginfo from "
+                                              << dbgInfoPath << NEWLINE;
+    loadLibraryInfo(dbgInfoPath, &debugBfdInfo);
+  }
+
+  if((debugBfdInfo.staticSymCnt == 0) && (debugBfdInfo.dynSymCnt == 0)){
+    PRINT_WARN_MSG_HEADER << "The same version of debuginfo not found: "
+                                    << libBfdInfo.bfdInfo->filename << NEWLINE;
+  }
+
   /* 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;
--- a/agent/src/symbolFinder.hpp	Tue Jun 18 13:07:18 2013 +0900
+++ b/agent/src/symbolFinder.hpp	Mon Jun 24 11:42:50 2013 +0900
@@ -65,6 +65,16 @@
 } TLibBFDInfo;
 
 /*!
+ * \brief .note.gnu.build-id information structure.
+ */
+typedef struct{
+  unsigned int name_size;  /*!< size of the name.              */
+  unsigned int hash_size;  /*!< size of the hash.              */
+  unsigned int identifier; /*!< NT_GNU_BUILD_ID == 0x3         */
+  char contents;           /*!< name ("GNU") & hash (build id) */
+} TBuildIdInfo;
+
+/*!
  * \brief C++ class for symbol search.
  */
 class TSymbolFinder{
--- a/agent/src/util.cpp	Tue Jun 18 13:07:18 2013 +0900
+++ b/agent/src/util.cpp	Mon Jun 24 11:42:50 2013 +0900
@@ -469,6 +469,8 @@
             arg.LogLevel = WARN;
           } else if (strcmp(value, "INFO") == 0) {
             arg.LogLevel = INFO;
+          } else if (strcmp(value, "DEBUG") == 0) {
+            arg.LogLevel = DEBUG;
           } else {
             PRINT_WARN_MSG_HEADER
               << "Ignore illegal configuration value."
--- a/agent/src/util.hpp	Tue Jun 18 13:07:18 2013 +0900
+++ b/agent/src/util.hpp	Mon Jun 24 11:42:50 2013 +0900
@@ -106,6 +106,26 @@
 #define PRINT_INFO_MSG(msg) \
   PRINT_INFO_MSG_HEADER << (msg) << NEWLINE
 
+/* Debug message. */
+
+/*!
+ * \brief Debug message header force macro.
+ */
+#define PRINT_DEBUG_MSG_HEADER_NOIF \
+    STDOUT << "heapstats DEBUG: "
+
+/*!
+ * \brief Debug message header macro.
+ */
+#define PRINT_DEBUG_MSG_HEADER \
+    if (arg.LogLevel >= DEBUG) PRINT_DEBUG_MSG_HEADER_NOIF
+
+/*!
+ * \brief Debug message macro.
+ */
+#define PRINT_DEBUG_MSG(msg) \
+    PRINT_DEBUG_MSG_HEADER << (msg) << NEWLINE
+
 /* Branch prediction. */
 
 /*!
@@ -214,8 +234,10 @@
   /*!< Level for  FATAL   error log. This's displayed by all means. */
   WARN = 2,
   /*!< Level for runnable error log. e.g. Heap-Alert                */
-  INFO = 3
+  INFO = 3,
   /*!< Level for  normal  info  log. e.g. Heap-Ranking              */
+  DEBUG = 4
+  /*!< Level for  debug  info  log.                                 */
 } TLogLevel;
 
 /*!