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

serviceability/sa/ClhsdbThreadContext.java fails with "'Thread "Common-Cleaner"' missing from stdout/stderr"

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P4
    • 20
    • 20
    • hotspot
    • None
    • b14

    Description

      Although the summary is rather specific, the root cause is much more general, and can cause a variety of test failures. We'll leave it specific to ClhsdbThreadContext.java for now. The test failed with:

      java.lang.RuntimeException: Test ERROR java.lang.RuntimeException: 'Thread "Common-Cleaner"' missing from stdout/stderr

      And indeed the Common-Cleaner thread dump is missing from the output. However, the root cause is an unexpected exception threadcontext dumping:

      Thread "C1 CompilerThread0" id=18 Address=0x00000253136a0650
      r15: 0x000000750e4ff2e8: In java stack for thread "C1 CompilerThread0" sun.jvm.hotspot.runtime.CompilerThread@0x00000253136a0650
      r14: 0x0000025377384470
      r13: null
      r12: 0x000000750e4ff378: In java stack for thread "C1 CompilerThread0" sun.jvm.hotspot.runtime.CompilerThread@0x00000253136a0650
      r11: 0x000000750e4fdeb8: In java stack for thread "C1 CompilerThread0" sun.jvm.hotspot.runtime.CompilerThread@0x00000253136a0650
      r10: 0x000000750e4fe7c0: In java stack for thread "C1 CompilerThread0" sun.jvm.hotspot.runtime.CompilerThread@0x00000253136a0650
      r9: null
      r8: 0x000000750e4fdffcError: java.lang.ArrayIndexOutOfBoundsException: Index 4099 out of bounds for length 4096
      java.lang.ArrayIndexOutOfBoundsException: Index 4099 out of bounds for length 4096
      at jdk.hotspot.agent/sun.jvm.hotspot.debugger.Page.getLong(Page.java:182)
      at jdk.hotspot.agent/sun.jvm.hotspot.debugger.PageCache.getLong(PageCache.java:100)
      at jdk.hotspot.agent/sun.jvm.hotspot.debugger.DebuggerBase.readCInteger(DebuggerBase.java:364)
      at jdk.hotspot.agent/sun.jvm.hotspot.debugger.DebuggerBase.readAddressValue(DebuggerBase.java:462)
      at jdk.hotspot.agent/sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.readAddress(WindbgDebuggerLocal.java:312)
      at jdk.hotspot.agent/sun.jvm.hotspot.debugger.windbg.WindbgAddress.getAddressAt(WindbgAddress.java:71)
      at jdk.hotspot.agent/sun.jvm.hotspot.utilities.PointerFinder.find(PointerFinder.java:58)
      at jdk.hotspot.agent/sun.jvm.hotspot.runtime.JavaThread.printThreadContextOn(JavaThread.java:493)
      at jdk.hotspot.agent/sun.jvm.hotspot.CommandProcessor$46.doit(CommandProcessor.java:1699)
      at jdk.hotspot.agent/sun.jvm.hotspot.CommandProcessor.executeCommand(CommandProcessor.java:2212)
      at jdk.hotspot.agent/sun.jvm.hotspot.CommandProcessor.executeCommand(CommandProcessor.java:2182)
      at jdk.hotspot.agent/sun.jvm.hotspot.CommandProcessor.run(CommandProcessor.java:2053)
      at jdk.hotspot.agent/sun.jvm.hotspot.CLHSDB.run(CLHSDB.java:112)
      at jdk.hotspot.agent/sun.jvm.hotspot.CLHSDB.main(CLHSDB.java:44)
      at jdk.hotspot.agent/sun.jvm.hotspot.SALauncher.runCLHSDB(SALauncher.java:281)
      at jdk.hotspot.agent/sun.jvm.hotspot.SALauncher.main(SALauncher.java:500)

      It looks like it's trying to fetch a 64-bit value (an address) that starts in the last 4-byte word of the page, so the read overflows the page. 64-bit values are expected always be 64-bit aligned.

      This exception is triggered by doing a PointerFinder.find() on $r8, which is 0x000000750e4fdffc, so this end result is not surprising given that threadcontext calls PointerFinder.find() on whatever (possibly random) value is in each register.

      PointerFinder.find() already expects a bad address to possibly fail with an exception, and it catches AddressException and WrongTypeException to deal with it (as do many other parts of SA code). I don't think adding ArrayIndexOutOfBoundsException to the list of possible exceptions is appropriate.

      It appears that a UnalignedAddressException (a subclass of AddressException) should have been thrown earlier on. There is in fact an alignment check made in DebuggerBase.readCInteger(), but the check is faulty:

                 public void checkAlignment(long address, long alignment) {
                   // Need to override default checkAlignment because we need to
                   // relax alignment constraints on Windows/x86
                   if ( (address % alignment != 0)
                      &&(alignment != 8 || address % 4 != 0)) {
                      throw new UnalignedAddressException(
                              "Trying to read at address: "
                            + addressValueToString(address)
                            + " with alignment: " + alignment,
                              address);
                   }
                 }

      It purposefully allows 4 byte alignment of 8 byte values in order to support 32-bit x86. However, I don't see how this softening of this check can be expected to work. If indeed 64-bit values on x86 are allowed to be just 4 byte aligned, then x86 can run into this same problem of trying to read a 64-bit value starting in the last 4 bytes of a page and continuing in the first 4 bytes of the next page. That will fail with the same exception we are seeing here, even if the address and 64-bit value are valid.

      So our options here are to either get rid of the support for 4 byte aligned 64-bit values (and hope it doesn't break x86), or modify the above check to only allow 4-byte alignment if getAddressSize() == 4.

      Attachments

        Issue Links

          Activity

            People

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

              Dates

                Created:
                Updated:
                Resolved: