changeset 14373:d7cb88bd7046

7127191: SA JSDB does not display native symbols correctly for transported Linux cores Summary: Better handle SA_ALTROOT Reviewed-by: sla, sspitsyn
author dsamersoff
date Wed, 12 Feb 2014 23:39:53 +0400
parents 46eeb3056482
children a33338c961e2
files agent/src/os/linux/libproc_impl.c agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
diffstat 3 files changed, 90 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/agent/src/os/linux/libproc_impl.c	Wed Feb 12 22:08:43 2014 +0400
+++ b/agent/src/os/linux/libproc_impl.c	Wed Feb 12 23:39:53 2014 +0400
@@ -29,54 +29,51 @@
 #include <thread_db.h>
 #include "libproc_impl.h"
 
-static const char* alt_root = NULL;
-static int alt_root_len = -1;
-
 #define SA_ALTROOT "SA_ALTROOT"
 
-static void init_alt_root() {
-   if (alt_root_len == -1) {
-      alt_root = getenv(SA_ALTROOT);
-      if (alt_root) {
-         alt_root_len = strlen(alt_root);
-      } else {
-         alt_root_len = 0;
-      }
-   }
-}
-
 int pathmap_open(const char* name) {
-   int fd;
-   char alt_path[PATH_MAX + 1];
+  static const char *alt_root = NULL;
+  static int alt_root_initialized = 0;
 
-   init_alt_root();
+  int fd;
+  char alt_path[PATH_MAX + 1], *alt_path_end;
+  const char *s;
 
-   if (alt_root_len > 0) {
-      strcpy(alt_path, alt_root);
-      strcat(alt_path, name);
-      fd = open(alt_path, O_RDONLY);
-      if (fd >= 0) {
-         print_debug("path %s substituted for %s\n", alt_path, name);
-         return fd;
-      }
+  if (!alt_root_initialized) {
+    alt_root_initialized = -1;
+    alt_root = getenv(SA_ALTROOT);
+  }
+
+  if (alt_root == NULL) {
+    return open(name, O_RDONLY);
+  }
+
+  strcpy(alt_path, alt_root);
+  alt_path_end = alt_path + strlen(alt_path);
 
-      if (strrchr(name, '/')) {
-         strcpy(alt_path, alt_root);
-         strcat(alt_path, strrchr(name, '/'));
-         fd = open(alt_path, O_RDONLY);
-         if (fd >= 0) {
-            print_debug("path %s substituted for %s\n", alt_path, name);
-            return fd;
-         }
-      }
-   } else {
-      fd = open(name, O_RDONLY);
-      if (fd >= 0) {
-         return fd;
-      }
-   }
+  // Strip path items one by one and try to open file with alt_root prepended
+  s = name;
+  while (1) {
+    strcat(alt_path, s);
+    s += 1;
+
+    fd = open(alt_path, O_RDONLY);
+    if (fd >= 0) {
+      print_debug("path %s substituted for %s\n", alt_path, name);
+      return fd;
+    }
 
-   return -1;
+    // Linker always put full path to solib to process, so we can rely
+    // on presence of /. If slash is not present, it means, that SOlib doesn't
+    // physically exist (e.g. linux-gate.so) and we fail opening it anyway
+    if ((s = strchr(s, '/')) == NULL) {
+      break;
+    }
+
+    *alt_path_end = 0;
+  }
+
+  return -1;
 }
 
 static bool _libsaproc_debug;
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java	Wed Feb 12 22:08:43 2014 +0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java	Wed Feb 12 23:39:53 2014 +0400
@@ -55,31 +55,21 @@
     if (pc == null) {
       return null;
     }
+
+    /* Typically we have about ten loaded objects here. So no reason to do
+      sort/binary search here. Linear search gives us acceptable performance.*/
+
     List objs = getLoadObjectList();
-    Object[] arr = objs.toArray();
-    // load objects are sorted by base address, do binary search
-    int mid  = -1;
-    int low  = 0;
-    int high = arr.length - 1;
 
-    while (low <= high) {
-       mid = (low + high) >> 1;
-       LoadObject midVal = (LoadObject) arr[mid];
-       long cmp = pc.minus(midVal.getBase());
-       if (cmp < 0) {
-          high = mid - 1;
-       } else if (cmp > 0) {
-          long size = midVal.getSize();
-          if (cmp >= size) {
-             low = mid + 1;
-          } else {
-             return (LoadObject) arr[mid];
-          }
-       } else { // match found
-          return (LoadObject) arr[mid];
-       }
+    for (int i = 0; i < objs.size(); i++) {
+      LoadObject ob = (LoadObject) objs.get(i);
+      Address base = ob.getBase();
+      long size = ob.getSize();
+      if ( pc.greaterThanOrEqual(base) && pc.lessThan(base.addOffsetTo(size))) {
+        return ob;
+      }
     }
-    // no match found.
+
     return null;
   }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Wed Feb 12 22:08:43 2014 +0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Wed Feb 12 23:39:53 2014 +0400
@@ -371,19 +371,23 @@
    return sa.dbg.lookup(dso, sym);
 }
 
-// returns the ClosestSymbol or null
-function closestSymbolFor(addr) {
-   if (sa.cdbg == null) {
+function loadObjectContainingPC(addr) {
+    if (sa.cdbg == null) {
       // no CDebugger support, return null
       return null;
-   } else {
-      var dso = sa.cdbg.loadObjectContainingPC(addr);
-      if (dso != null) {
-         return dso.closestSymbolToPC(addr);
-      } else {
-         return null;
-      }
-   }
+    }
+
+    return  sa.cdbg.loadObjectContainingPC(addr);
+}
+
+// returns the ClosestSymbol or null
+function closestSymbolFor(addr) {
+    var dso = loadObjectContainingPC(addr);
+    if (dso != null) {
+      return dso.closestSymbolToPC(addr);
+    }
+
+    return null;
 }
 
 // Address-to-symbol
@@ -884,21 +888,29 @@
 
 // returns description of given pointer as a String
 function whatis(addr) {
-   addr = any2addr(addr);
-   var ptrLoc = findPtr(addr);
-   if (ptrLoc.isUnknown()) {
-      var vmType = vmTypeof(addr);
-      if (vmType != null) {
-         return "pointer to " + vmType.name;
-      } else {
-         var sym = closestSymbolFor(addr);
-         if (sym != null) {
-            return sym.name + '+' + sym.offset;
-         } else {
-            return ptrLoc.toString();
-         }
-      }
-   } else {
-      return ptrLoc.toString();
-   }
+  addr = any2addr(addr);
+  var ptrLoc = findPtr(addr);
+  if (!ptrLoc.isUnknown()) {
+    return ptrLoc.toString();
+  }
+
+  var vmType = vmTypeof(addr);
+  if (vmType != null) {
+    return "pointer to " + vmType.name;
+  }
+
+  var dso = loadObjectContainingPC(addr);
+  if (dso == null) {
+    return ptrLoc.toString();
+  }
+
+  var sym = dso.closestSymbolToPC(addr);
+  if (sym != null) {
+    return sym.name + '+' + sym.offset;
+  }
+
+  var s = dso.getName();
+  var p = s.lastIndexOf("/");
+  var base = dso.getBase();
+  return s.substring(p+1, s.length) + '+' + addr.minus(base);
 }