# HG changeset patch # User dsamersoff # Date 1392233993 -14400 # Node ID d7cb88bd7046435522f65343be9cc5fce99dbd32 # Parent 46eeb3056482d95c9005f335302d84b829536cd4 7127191: SA JSDB does not display native symbols correctly for transported Linux cores Summary: Better handle SA_ALTROOT Reviewed-by: sla, sspitsyn diff -r 46eeb3056482 -r d7cb88bd7046 agent/src/os/linux/libproc_impl.c --- 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 #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; diff -r 46eeb3056482 -r d7cb88bd7046 agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java --- 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; } diff -r 46eeb3056482 -r d7cb88bd7046 agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js --- 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); }