Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8261702

ClhsdbFindPC can fail due to PointerFinder incorrectly thinking an address is in a .so

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 17
    • Fix Version/s: 17
    • Component/s: hotspot
    • Labels:
      None
    • Subcomponent:
    • Resolved In Build:
      b11

      Description

      I had one test failure of ClhsdbFindPC that I could not reproduce again, but I'm pretty sure I know the cause. The part of the test that failed was using findpc on a pc address from the jstack output, and that address was in the interpreter. However, findpc found it at some large offset from the start of a .so without a symbol match.

      The cause is due to a known issue with the Linux DSO.java support. A DSO is created for each .so. There is a bug that results in the size given to the created DSO to end up being too large. It is the size of the file rather than the size of the actual mapped in segments. For the most part this is harmless, and when an address is in a .so, findpc will find the proper .so and symbol for it. However, if the address is just outside of the .so, PointerFinder can think it is inside of it. Here's the relevant code:

              loc.loadObject = cdbg.loadObjectContainingPC(a);
              if (loc.loadObject != null) {
                  loc.nativeSymbol = loc.loadObject.closestSymbolToPC(a);
                  return loc;
              }

      loadObjectContainingPC(a) returns the DSO that contains the address. As mentioned above, this might not always be accurate. If the address is not actually in the returned DSO, but is in some DSO, then the call to loadObject.closestSymbolToPC() will still work properly because it actually ignores the DSO info and just searches all DSO's from native to find the symbol in the correct DSO, even if it was not the specified DSO.

      However, if the address is not in and DSO, yet a DSO was returned by loadObjectContainingPC(), then there are problems. The most likely way this will happen is when specifying an address just after the last DSO in memory. In the case of this bug the address was in the interpreter. However, because this code thinks it is in a DSO (and we haven't yet done the check to see if it is in the interpreter), we end up calling loadObject.closestSymbolToPC(a). This will fail to find a symbol match, but that is not an indication of failure because not all addresses in a DSO have a symbol associated with them. So then we later end up in the code that prints the findpc info for the address:

              if (nativeSymbol != null) {
                  String name = nativeSymbol.getName();
                  if (cdbg.canDemangle()) {
                      name = cdbg.demangle(name);
                  }
                  tty.print(name);
                  diff = nativeSymbol.getOffset();
              } else {
                  tty.print(loadObject.getName());
                  diff = addr.minus(loadObject.getBase());
              }
              if (diff != 0L) {
                  tty.print(" + 0x" + Long.toHexString(diff));
              }

      in this case nativeSymbol is null, so we just end up printing the name of the DSO plus the offset from the start of the DSO. The test fails because what it expected was for "In interpreter codelet:" to appear in the output.

      The workaround for this DSO bug is simple. Just have PointerFinder defer searching DSOs for the address to be the last thing it does. That way we will first attempt to find the address in the interpreter.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              cjplummer Chris Plummer
              Reporter:
              cjplummer Chris Plummer
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: