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.