JDK-8013942 : JSR 292: assert(type() == T_OBJECT) failed: type check
  • Type: Bug
  • Component: hotspot
  • Sub-Component: jvmti
  • Affected Version: hs24,hs25,7u40,8u60,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2013-05-06
  • Updated: 2015-09-29
  • Resolved: 2014-07-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u60Fixed 9 b25Fixed
Related Reports
Blocks :  
Relates :  
Description
Crash observed on all platforms on fastdebug VM:

;; Using jvm: "/export/local/aurora/sandbox/sca/vmsqe/jdk/pit/2013-05-03-151437.amurillo.hs25-b31-snapshot/fastdebug/linux-amd64/jre/lib/amd64/server/libjvm.so"
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/opt/jprt/T/P1/151437.amurillo/s/src/share/vm/runtime/stackValue.hpp:64), pid=4248, tid=1077950784
#  assert(type() == T_OBJECT) failed: type check
#
# JRE version: Java(TM) SE Runtime Environment (8.0-b87) (build 1.8.0-ea-fastdebug-b87)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.0-b31-internal-201305031514.amurillo.hs25-b31-snapshot-fastdebug mixed mode linux-amd64 compressed oops)
# Core dump written. Default location: /export/local/aurora/sandbox/results/ResultDir/breakpointOtherStratum/core or core.4248
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#

---------------  T H R E A D  ---------------

Current thread (0x00000000006c3000):  VMThread [stack: 0x0000000040303000,0x0000000040404000] [id=4253]

Stack: [0x0000000040303000,0x0000000040404000],  sp=0x0000000040402440,  free space=1021k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0xdc6282]  VMError::report_and_die()+0x302/usr/bin/nm: /export/local/aurora/sandbox/sca/vmsqe/jdk/pit/2013-05-03-151437.amurillo.hs25-b31-snapshot/fastdebug/linux-amd64/jre/lib/amd64/server/libjvm.so: File format not recognized
Warning: /export/local/aurora/sandbox/sca/vmsqe/jdk/pit/2013-05-03-151437.amurillo.hs25-b31-snapshot/fastdebug/linux-amd64/jre/lib/amd64/server/libjvm.so exists but has been stripped

V  [libjvm.so+0x6952c4]  report_vm_error(char const*, int, char const*, char const*)+0x84
V  [libjvm.so+0xcc83cd]  StackValueCollection::obj_at(int) const+0x6d
V  [libjvm.so+0x9e9f75]  VM_GetOrSetLocal::doit()+0x485
V  [libjvm.so+0xdef569]  VM_Operation::evaluate()+0x89
V  [libjvm.so+0xdec991]  VMThread::evaluate_operation(VM_Operation*)+0xb1
V  [libjvm.so+0xdedc40]  VMThread::loop()+0x660
V  [libjvm.so+0xdede70]  VMThread::run()+0xb0
V  [libjvm.so+0xb9b238]  java_start(Thread*)+0x108

VM_Operation (0x00000000408068e0): GetOrSetLocal, mode: safepoint, requested by thread 0x0000000000740000

Comments
The suggested fix is to use the oop_mask for the method's current bci. It tells when the local is dead in the scope of current bci. Return the JVMTI_ERROR_INVALID_SLOT error in such a case. The full patch is: % hg diff diff -r fdcc91703a7e src/share/vm/interpreter/oopMapCache.cpp --- a/src/share/vm/interpreter/oopMapCache.cpp Thu Jun 12 15:57:16 2014 -0700 +++ b/src/share/vm/interpreter/oopMapCache.cpp Wed Jun 25 04:13:07 2014 -0700 @@ -244,10 +244,8 @@ void InterpreterOopMap::print() { method()->print_value(); tty->print(" @ %d = [%d] { ", bci(), n); for (int i = 0; i < n; i++) { -#ifdef ENABLE_ZAP_DEAD_LOCALS if (is_dead(i)) tty->print("%d+ ", i); else -#endif if (is_oop(i)) tty->print("%d ", i); } tty->print_cr("}"); @@ -402,13 +400,11 @@ void OopMapCacheEntry::set_mask(CellType value |= (mask << oop_bit_number ); } - #ifdef ENABLE_ZAP_DEAD_LOCALS // set dead bit if (!cell->is_live()) { value |= (mask << dead_bit_number); assert(!cell->is_reference(), "dead value marked as oop"); } - #endif } // make sure last word is stored diff -r fdcc91703a7e src/share/vm/interpreter/oopMapCache.hpp --- a/src/share/vm/interpreter/oopMapCache.hpp Thu Jun 12 15:57:16 2014 -0700 +++ b/src/share/vm/interpreter/oopMapCache.hpp Wed Jun 25 04:13:07 2014 -0700 @@ -73,12 +73,8 @@ class InterpreterOopMap: ResourceObj { // small_mask_limit can be set to 0 // for testing bit_mask allocation -#ifdef ENABLE_ZAP_DEAD_LOCALS bits_per_entry = 2, dead_bit_number = 1, -#else - bits_per_entry = 1, -#endif oop_bit_number = 0 }; @@ -120,10 +116,6 @@ class InterpreterOopMap: ResourceObj { void set_expression_stack_size(int sz) { _expression_stack_size = sz; } -#ifdef ENABLE_ZAP_DEAD_LOCALS - bool is_dead(int offset) { return (entry_at(offset) & (1 << dead_bit_number)) != 0; } -#endif - // Lookup bool match(methodHandle method, int bci) { return _method == method() && _bci == bci; } bool is_empty(); @@ -144,6 +136,7 @@ class InterpreterOopMap: ResourceObj { void iterate_oop(OffsetClosure* oop_closure); void print(); + bool is_dead(int offset) { return (entry_at(offset) & (1 << dead_bit_number)) != 0; } bool is_oop (int offset) { return (entry_at(offset) & (1 << oop_bit_number )) != 0; } int expression_stack_size() { return _expression_stack_size; } diff -r fdcc91703a7e src/share/vm/prims/jvmtiImpl.cpp --- a/src/share/vm/prims/jvmtiImpl.cpp Thu Jun 12 15:57:16 2014 -0700 +++ b/src/share/vm/prims/jvmtiImpl.cpp Wed Jun 25 04:13:07 2014 -0700 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/systemDictionary.hpp" #include "interpreter/interpreter.hpp" +#include "interpreter/oopMapCache.hpp" #include "jvmtifiles/jvmtiEnv.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" @@ -744,6 +745,13 @@ bool VM_GetOrSetLocal::doit_prologue() { } void VM_GetOrSetLocal::doit() { + InterpreterOopMap oop_mask; + _jvf->method()->mask_for(_jvf->bci(), &oop_mask); + if (oop_mask.is_dead(_index)) { + // The local can be invalid and uninitialized in the scope of current bci + _result = JVMTI_ERROR_INVALID_SLOT; + return; + } if (_set) { // Force deoptimization of frame if compiled because it's // possible the compiler emitted some locals as constant values,
25-06-2014

More details about why the assert is fired. One of the methods that causes the issue is 'canonicalize()': static Class<?> canonicalize(Class<?> t, int how) { Class<?> ct; if (t == Object.class) { // no change, ever } else if (!t.isPrimitive()) { switch (how) { case UNWRAP: ct = Wrapper.asPrimitiveType(t); if (ct != t) return ct; break; case RAW_RETURN: case ERASE: return Object.class; } } else if (t == void.class) { // no change, usually switch (how) { case RAW_RETURN: return int.class; case WRAP: return Void.class; } } else { // non-void primitive switch (how) { case WRAP: return Wrapper.asWrapperType(t); case INTS: if (t == int.class || t == long.class) return null; // no change if (t == double.class) return long.class; return int.class; case LONGS: if (t == long.class) return null; // no change return long.class; case RAW_RETURN: if (t == int.class || t == long.class || t == float.class || t == double.class) return null; // no change // everything else returns as an int return int.class; } } // no change; return null to signify return null; } This is my tracing: debugee.stdout> MY_TRACE: TYPE_MISMATCH: dep: 0, bci: 70, idx: 2, _type: 12, valp->type(): 10 debugee.stdout> MY_TRACE: method: java/lang/invoke/MethodTypeForm:canonicalize(Ljava/lang/Class;I)Ljava/lang/Class; debugee.stdout> MY_TRACE: TYPE_MISMATCH: dep: 0, bci: 70, idx: 2, _type: 12, valp->type(): 10 debugee.stdout> MY_TRACE: method: java/lang/invoke/MethodTypeForm:canonicalize(Ljava/lang/Class;I)Ljava/lang/Class; debugee.stdout> MY_TRACE: TYPE_MISMATCH: dep: 0, bci: 77, idx: 2, _type: 12, valp->type(): 10 debugee.stdout> MY_TRACE: method: java/lang/invoke/MethodTypeForm:canonicalize(Ljava/lang/Class;I)Ljava/lang/Class; debugee.stdout> MY_TRACE: TYPE_MISMATCH: dep: 0, bci: 2187, idx: 9, _type: 12, valp->type(): 10 debugee.stdout> MY_TRACE: method: jdk/internal/org/objectweb/asm/Frame:execute(IILjdk/internal/org/objectweb/asm/ClassWriter;Ljdk/internal/org/objectweb/asm/Item;)V The test is trying to getLocalObject() for the index 2 which is the local variable ' Class<?> ct'. The variable is available only in the scope of the condition at the lines 321-330: } else if (!t.isPrimitive()) { switch (how) { case UNWRAP: ct = Wrapper.asPrimitiveType(t); if (ct != t) return ct; break; case RAW_RETURN: case ERASE: return Object.class; } The variable 'ct' should be normally unavailable out of this scope. However, the test is trying to get its value when the current method location (bci) is out of the 'ct' scope: debugee.stdout> MY_TRACE: TYPE_MISMATCH: dep: 0, bci: 70, idx: 2, _type: 12, valp->type(): 10 debugee.stdout> MY_TRACE: method: java/lang/invoke/MethodTypeForm:canonicalize(Ljava/lang/Class;I)Ljava/lang/Class; debugee.stdout> MY_TRACE: TYPE_MISMATCH: dep: 0, bci: 77, idx: 2, _type: 12, valp->type(): 10 debugee.stdout> MY_TRACE: method: java/lang/invoke/MethodTypeForm:canonicalize(Ljava/lang/Class;I)Ljava/lang/Class; The location must be in the range from bci=16 to the bci=66 in order to match the scope: 9: aload_0 10: invokevirtual #54 // Method java/lang/Class.isPrimitive:()Z 13: ifne 70 16: iload_1 17: lookupswitch { // 3 1: 64 3: 52 6: 64 default: 67 } 52: aload_0 53: invokestatic #55 // Method sun/invoke/util/Wrapper.asPrimitiveType:(Ljava/lang/Class;)Ljava/lang/Class; 56: astore_2 57: aload_2 58: aload_0 59: if_acmpeq 67 62: aload_2 63: areturn 64: ldc #19 // class java/lang/Object 66: areturn However, the current bci (location) is 70 or 77 when the assert is hit. Both of these locations are out of the variable 'ct' scope: 67: goto 231 70: aload_0 71: getstatic #27 // Field java/lang/Void.TYPE:Ljava/lang/Class; 74: if_acmpne 114 77: iload_1 78: lookupswitch { // 2 2: 108 6: 104 default: 111 } 104: getstatic #23 // Field java/lang/Integer.TYPE:Ljava/lang/Class; 107: areturn Moreover, the value of the 'ct' has not been initialized and will not be initialized because the instructions 16-66 that could do it were not executed. This is why the type of value of the local 'ct' remained to be default: T_INT. The above matches the following source lines: } else if (t == void.class) { // no change, usually switch (how) { case RAW_RETURN: return int.class; case WRAP: return Void.class; } This is the javap full output for the method canonicalize(): static java.lang.Class<?> canonicalize(java.lang.Class<?>, int); descriptor: (Ljava/lang/Class;I)Ljava/lang/Class; flags: ACC_STATIC Code: stack=2, locals=3, args_size=2 0: aload_0 1: ldc #19 // class java/lang/Object 3: if_acmpne 9 6: goto 231 9: aload_0 10: invokevirtual #54 // Method java/lang/Class.isPrimitive:()Z 13: ifne 70 16: iload_1 17: lookupswitch { // 3 1: 64 3: 52 6: 64 default: 67 } 52: aload_0 53: invokestatic #55 // Method sun/invoke/util/Wrapper.asPrimitiveType:(Ljava/lang/Class;)Ljava/lang/Class; 56: astore_2 57: aload_2 58: aload_0 59: if_acmpeq 67 62: aload_2 63: areturn 64: ldc #19 // class java/lang/Object 66: areturn 67: goto 231 70: aload_0 71: getstatic #27 // Field java/lang/Void.TYPE:Ljava/lang/Class; 74: if_acmpne 114 77: iload_1 78: lookupswitch { // 2 2: 108 6: 104 default: 111 } 104: getstatic #23 // Field java/lang/Integer.TYPE:Ljava/lang/Class; 107: areturn 108: ldc #56 // class java/lang/Void 110: areturn 111: goto 231 114: iload_1 115: tableswitch { // 2 to 6 2: 148 3: 231 4: 153 5: 184 6: 197 default: 231 } 148: aload_0 149: invokestatic #57 // Method sun/invoke/util/Wrapper.asWrapperType:(Ljava/lang/Class;)Ljava/lang/Class; 152: areturn 153: aload_0 154: getstatic #23 // Field java/lang/Integer.TYPE:Ljava/lang/Class; 157: if_acmpeq 167 160: aload_0 161: getstatic #58 // Field java/lang/Long.TYPE:Ljava/lang/Class; 164: if_acmpne 169 167: aconst_null 168: areturn 169: aload_0 170: getstatic #59 // Field java/lang/Double.TYPE:Ljava/lang/Class; 173: if_acmpne 180 176: getstatic #58 // Field java/lang/Long.TYPE:Ljava/lang/Class; 179: areturn 180: getstatic #23 // Field java/lang/Integer.TYPE:Ljava/lang/Class; 183: areturn 184: aload_0 185: getstatic #58 // Field java/lang/Long.TYPE:Ljava/lang/Class; 188: if_acmpne 193 191: aconst_null 192: areturn 193: getstatic #58 // Field java/lang/Long.TYPE:Ljava/lang/Class; 196: areturn 197: aload_0 198: getstatic #23 // Field java/lang/Integer.TYPE:Ljava/lang/Class; 201: if_acmpeq 225 204: aload_0 205: getstatic #58 // Field java/lang/Long.TYPE:Ljava/lang/Class; 208: if_acmpeq 225 211: aload_0 212: getstatic #60 // Field java/lang/Float.TYPE:Ljava/lang/Class; 215: if_acmpeq 225 218: aload_0 219: getstatic #59 // Field java/lang/Double.TYPE:Ljava/lang/Class; 222: if_acmpne 227 225: aconst_null 226: areturn 227: getstatic #23 // Field java/lang/Integer.TYPE:Ljava/lang/Class; 230: areturn 231: aconst_null 232: areturn
19-06-2014

Continue analysis ... It seems to me that the JVMTI must return the JVMTI_ERROR_TYPE_MISMATCH in this case. I will try to come up with the fix to do so.
18-06-2014

One of the approaches to fix the bug (or workarounds) would be to check the type and value of the local object and if the type does not match and the value is 0 then to return the null reference. This would match an uninitialized object case. The only issue here is that there is no good way to prove that we did not hit a wrong spot. In the latter case it would be more correct to return the JVMTI_ERROR_TYPE_MISMATCH.
18-06-2014

It is still a question what is wrong with the method: java/lang/invoke/MethodTypeForm:canonicalize(Ljava/lang/Class;I)Ljava/lang/Class; as the VM thinks that the variable "Class<?> ct" is of integer type. Below are some details on how it looks like on the debugger side. This is an InconsistentDebugInfoException stack trace (produced if the JVMTI returns the TYPE_MISMATCH): ERROR: Exception when getting stack trace # ERROR: com.sun.jdi.InconsistentDebugInfoException # ERROR: at com.sun.tools.jdi.JDWPException.toJDIException(JDWPException.java:61) # ERROR: at com.sun.tools.jdi.StackFrameImpl.getValues(StackFrameImpl.java:241) # ERROR: at vm.mlvm.share.jdi.JDIBreakpointTest.getStackTraceStr(JDIBreakpointTest.java:459) # ERROR: at vm.mlvm.share.jdi.JDIBreakpointTest.run(JDIBreakpointTest.java:247) # ERROR: at vm.mlvm.share.MlvmTest.runMlvmTest(MlvmTest.java:225) # ERROR: at vm.mlvm.share.MlvmTest.launch(MlvmTest.java:141) # ERROR: at vm.mlvm.share.MlvmTest.launch(MlvmTest.java:106) # ERROR: at vm.mlvm.share.jdi.JDIBreakpointTest.main(JDIBreakpointTest.java:519) These are the relevant code fragments: vm.mlvm.share.jdi.JDIBreakpointTest.java: public static String getStackTraceStr(List<StackFrame> frames, boolean full) throws AbsentInformationException { try { StringBuffer buf = new StringBuffer(); int frameNum = 0; for (StackFrame f : frames) { Location l = f.location(); buf.append(String.format("#%-4d", frameNum)).append(l.method()) .append("\n source: ").append(l.sourcePath()) .append(":").append(l.lineNumber()).append("; bci=") .append(l.codeIndex()).append("\n class: ") .append(l.declaringType()).append("\n strata: ") .append(StratumUtils.getStrataStr(f)).append("\n locals: "); try { for (Map.Entry<LocalVariable, Value> m : f.getValues(f.visibleVariables()).entrySet()) { <===== Here!!! com.sun.tools.jdi.StackFrameImpl.java: public Map<LocalVariable, Value> getValues(List<? extends LocalVariable> variables) { validateStackFrame(); validateMirrors(variables); int count = variables.size(); JDWP.StackFrame.GetValues.SlotInfo[] slots = new JDWP.StackFrame.GetValues.SlotInfo[count]; for (int i=0; i<count; ++i) { LocalVariableImpl variable = (LocalVariableImpl)variables.get(i); if (!variable.isVisible(this)) { throw new IllegalArgumentException(variable.name() + " is not valid at this frame location"); } slots[i] = new JDWP.StackFrame.GetValues.SlotInfo(variable.slot(), (byte)variable.signature().charAt(0)); <===== This is how the type of local is identified } PacketStream ps; /* protect against defunct frame id */ synchronized (vm.state()) { validateStackFrame(); ps = JDWP.StackFrame.GetValues.enqueueCommand(vm, thread, id, slots); } /* actually get it, now that order is guaranteed */ ValueImpl[] values; try { values = JDWP.StackFrame.GetValues.waitForReply(vm, ps).values; } catch (JDWPException exc) { switch (exc.errorCode()) { case JDWP.Error.INVALID_FRAMEID: case JDWP.Error.THREAD_NOT_SUSPENDED: case JDWP.Error.INVALID_THREAD: throw new InvalidStackFrameException(); default: throw exc.toJDIException(); <============ Here !!! } } com.sun.tools.jdi.JDWPException.java: RuntimeException toJDIException() { switch (errorCode) { case JDWP.Error.INVALID_OBJECT: return new ObjectCollectedException(); case JDWP.Error.VM_DEAD: return new VMDisconnectedException(); case JDWP.Error.OUT_OF_MEMORY: return new VMOutOfMemoryException(); case JDWP.Error.CLASS_NOT_PREPARED: return new ClassNotPreparedException(); case JDWP.Error.INVALID_FRAMEID: case JDWP.Error.NOT_CURRENT_FRAME: return new InvalidStackFrameException(); case JDWP.Error.NOT_IMPLEMENTED: return new UnsupportedOperationException(); case JDWP.Error.INVALID_INDEX: case JDWP.Error.INVALID_LENGTH: return new IndexOutOfBoundsException(); case JDWP.Error.TYPE_MISMATCH: return new InconsistentDebugInfoException(); <====== Here !!! case JDWP.Error.INVALID_THREAD: return new IllegalThreadStateException(); default: return new InternalException("Unexpected JDWP Error: " + errorCode, errorCode); } }
14-06-2014

Now I can reliably reproduce this exact pattern. Below is what is possible to see so far. The target debuggee thread is this: ----------------- lwp# 2 / thread# 2 -------------------- ffffffff7e8dc6a8 ___lwp_cond_wait (1001adc50, 1001adc38, 1, ffffffff, ffffffff7e8c20e8, ffffffffffffffff) + 8 ffffffff7d377080 void os::PlatformEvent::park() (1001adc00, 188400, 1001adc38, 1001adc50, ffffffff7dc8bea5, ffffffff7dfc15d8) + 140 ffffffff7d2e4f1c int Monitor::IWait(Thread*,long) (1001a81d8, 1001ad000, 0, c1280, 1001ad000, 1001adc00) + d4 ffffffff7d2e62b8 bool Monitor::wait(bool,long,bool) (1001a81d8, 1001ad000, 0, 0, ffffffff7dc3de0b, cdb4c4) + 1a8 ffffffff7d5f0be4 int JavaThread::java_suspend_self() (1001ad000, 1, 40000000, 60000000, 40000000, 1001ad030) + 1b0 ffffffff7d0e1b20 int JvmtiRawMonitor::raw_wait(long,bool,Thread*) (1001ad000, ffffffffffffffff, ffffffff7e0d1a78, 20000000, 10051df38, 1) + 290 ffffffff7d0a3924 jvmtiError JvmtiEnv::RawMonitorWait(JvmtiRawMonitor*,long) (1001ad000, 10051df38, ffffffffffffffff, ffffffff7db598da, ffffffff7dfc15d8, 4) + cc ffffffff7a22dc78 debugMonitorWait (ffffffff7a33a2b8, ffffffff7a33a388, b38, ffffffff7a339780, 10bb44, 800) + 40 ffffffff7a21bef4 enqueueCommand (101475558, 0, ffffffffffefd238, ffffffff7a339780, 102c00, ffffffff7a33a6d8) + 154 ffffffff7a21d86c eventHelper_reportEvents (78, 1016273d8, 101475558, 0, 1, 1) + 114 ffffffff7a2179f4 reportEvents (1001ad230, ffffffff7a339780, 10147f5b0, 1, 1016273d8, 1013bf880) + 134 ffffffff7a217f70 event_callback (1001ad230, ffffffff7a8fcc30, ffffffff7a22266c, 0, ffffffff7a339780, 100515ee8) + 360 ffffffff7a2182f0 cbSingleStep (10010a820, 1001ad230, 10147f5b0, 1013bf880, 46, ffffffff7a33a26c) + 108 ffffffff7d0c08ec void JvmtiExport::post_single_step(JavaThread*,Method*,unsigned char*) (1001ad000, 0, ffffffff5ca2773e, 0, ffffffff7a2181e8, 10010a818) + 814 ffffffff7d0bb94c void JvmtiExport::at_single_stepping_point(JavaThread*,Method*,unsigned char*) (1001ad000, 0, ffffffff5ca2773e, ffffffff7e1ab7f0, 0, ffffffff7a8fd058) + 20c ffffffff7ce3eea4 void InterpreterRuntime::at_safepoint(JavaThread*) (ffffffff5ca27838, 1001ad000, 1, 1001ad210, ffffffff7dfc15d8, 1001ad000) + 214 ffffffff678206fc * java/lang/invoke/MethodTypeForm.canonicalize(Ljava/lang/Class;I)Ljava/lang/Class;+70 ffffffff67807da8 * java/lang/invoke/MethodTypeForm.canonicalizes([Ljava/lang/Class;I)[Ljava/lang/Class;+19 ffffffff67807da8 * java/lang/invoke/MethodTypeForm.canonicalize(Ljava/lang/invoke/MethodType;II)Ljava/lang/invoke/MethodType;+7 ffffffff67807da8 * java/lang/invoke/MethodType.wrapWithPrims(Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodType;+33 ffffffff67807da8 * java/lang/invoke/MethodType.wrap()Ljava/lang/invoke/MethodType;+8 ffffffff67807da8 * java/lang/invoke/InvokerBytecodeGenerator.generateNamedFunctionInvokerImpl(Ljava/lang/invoke/MethodTypeForm;)[B+84 ffffffff67807da8 * java/lang/invoke/InvokerBytecodeGenerator.generateNamedFunctionInvoker(Ljava/lang/invoke/MethodTypeForm;)Ljava/lang/invoke/MemberName;+31 ffffffff67807da8 * java/lang/invoke/LambdaForm$NamedFunction.computeInvoker(Ljava/lang/invoke/MethodTypeForm;)Ljava/lang/invoke/MethodHandle;+12 ffffffff67807da8 * java/lang/invoke/LambdaForm$NamedFunction.invoker()Ljava/lang/invoke/MethodHandle;+20 ffffffff67807da8 * java/lang/invoke/LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object;+38 ffffffff67807da8 * java/lang/invoke/LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object;+117 ffffffff67807da8 * java/lang/invoke/LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object;+67 ffffffff67807da8 * java/lang/invoke/LambdaForm$LFI.interpret_L(Ljava/lang/invoke/MethodHandle;Ljava/lang/Object;)Ljava/lang/Object;+17 ffffffff67807da8 * java/lang/invoke/LambdaForm$NamedFunction.invoke_L_L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;+24 ffffffff67807da8 * java/lang/invoke/LambdaForm$DMH.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+11 ffffffff67807da8 * java/lang/invoke/LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object;+46 ffffffff67807da8 * java/lang/invoke/LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object;+117 ffffffff67807da8 * java/lang/invoke/LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object;+67 ffffffff67807da8 * java/lang/invoke/LambdaForm$LFI.interpret_L(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;+13 ffffffff67807da8 * java/lang/invoke/LambdaForm$NamedFunction.invoke__L(Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;+20 ffffffff67807da8 * java/lang/invoke/LambdaForm$DMH.invokeStatic_LL_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+11 ffffffff67807da8 * java/lang/invoke/LambdaForm$NamedFunction.invokeWithArguments([Ljava/lang/Object;)Ljava/lang/Object;+46 ffffffff67807da8 * java/lang/invoke/LambdaForm.interpretName(Ljava/lang/invoke/LambdaForm$Name;[Ljava/lang/Object;)Ljava/lang/Object;+117 ffffffff67807da8 * java/lang/invoke/LambdaForm.interpretWithArguments([Ljava/lang/Object;)Ljava/lang/Object;+67 ffffffff67807da8 * java/lang/invoke/LambdaForm$LFI.interpret_L(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;+13 ffffffff67807da8 * java/lang/invoke/LambdaForm$MH.invokeExact_MT(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+9 ffffffff67807da8 * vm/mlvm/share/jpda/SDE_MHDebuggeeBase.invokeMH()Ljava/lang/Object;+4 ffffffff67807da8 * vm/mlvm/share/jpda/SDE_MHDebuggeeBase.runDebuggee()Z+1 ffffffff67807638 * vm/mlvm/share/jpda/Debuggee.run()Z+76 ffffffff67807638 * vm/mlvm/share/MlvmTest.runMlvmTest(Ljava/lang/Class;)Z+113 ffffffff67807638 * vm/mlvm/share/MlvmTest.launch()V+133 ffffffff67807eb8 * vm/mlvm/share/MlvmTest.launch(Lnsk/share/ArgumentParser;)V+4 ffffffff67807eb8 * vm/mlvm/share/jdi/MHDebuggee.main([Ljava/lang/String;)V+8 ffffffff678004b4 * StubRoutines (1) ffffffff7ce554d4 void JavaCalls::call_helper(JavaValue*,methodHandle*,JavaCallArguments*,Thread*) (ffffffff7a8ffe10, 1, ffffffff5cc00268, 1001ad000, ffffffff67800400, 0) + 6f4 ffffffff7ceebbf4 void jni_invoke_static(JNIEnv_*,JavaValue*,_jobject*,JNICallType,_jmethodID*,JNI_ArgumentPusher*,Thread*) (1001ad230, ffffffff7a8ffe10, 1, 10049bb18, ffffffff7a8ffa80, 100139b48) + a9c ffffffff7cf1613c jni_CallStaticVoidMethod (1001ad230, e, 10072ecb8, 1001ad000, ffffffff7a8ffdd0, 1800) + 524 ffffffff7ee06840 JavaMain (ffffffff7cee7308, 1001380d0, 100101640, ffffffff7ee15018, ffffffff7e0aca88, 10072ecb8) + 570 ffffffff7e8d8558 _lwp_start (0, 0, 0, 0, 0, 0) In my TMP hack I've added the call to the StackValueCollection::obj_at() into the VM_GetOrSetLocal::check_slot_type(). This helps to see the related JDWP agent thread that has this stack trace: ----------------- lwp# 12 / thread# 12 -------------------- ffffffff7e8dc5c4 _lwp_kill (6, 0, ffffffff7ea49960, ffffffffffffffff, ffffffff7ea3e000, 0) + 8 ffffffff7e84c0e0 abort (1, 1d8, ffffffff7d37eba0, 1f202c, 0, 0) + 118 ffffffff7d36ae40 void os::abort(bool) (ffffffff7dc87930, ffffffff7e082f70, 1, ffffffff7e0dd658, ffffffff59ffe610, ffffffff7e0dd658) + 170 ffffffff7d6a70f4 void VMError::report_and_die() (1, c1000, 0, ffffffff00000002, e0000001, 15162e) + 1054 ffffffff7cb4bf28 void report_vm_error(const char*,int,const char*,const char*) (ffffffff7d962ab8, 43, ffffffff7d962b11, ffffffff7d962b33, c1124, 147571c) + 70 ffffffff7cb77cd4 Handle StackValue::get_obj()const (101c9a658, ffffffffff9a14af, 144994c, 65e800, ffffffff7dfc15d8, a) + 5c ffffffff7d5105b4 Handle StackValueCollection::obj_at(int)const (101c9a578, 2, 0, 2, ffffffff7ea3e000, 9b) + 10 ffffffff7d0daa04 bool VM_GetOrSetLocal::check_slot_type(javaVFrame*) (ffffffff59fff1a0, 101c9a088, ffffffff5ca27838, c, 101c9a6a8, 101c9a558) + 314 ffffffff7d0db088 bool VM_GetOrSetLocal::doit_prologue() (ffffffff59fff1a0, 0, ffffffff7d0dafe8, ffffffff7e0b7c58, 0, ffffffffffdd5b1e) + a0 ffffffff7d6d3a28 void VMThread::execute(VM_Operation*) (ffffffff59fff1a0, ffffffff7cad6270, ffffffff7e0b7d88, ffffffff7dfc15d8, 10051a000, 0) + 88 ffffffff7d09ca5c jvmtiError JvmtiEnv::GetLocalObject(JavaThread*,int,int,_jobject**) (ffffffff59fff208, 1001ad000, 0, 2, ffffffff59fff428, f24bc4) + 4c ffffffff7cffb588 jvmti_GetLocalObject (c1400, 38, 0, 2, ffffffff59fff428, 1001ad000) + 528 ffffffff7a209678 writeVariableValue (10051a230, ffffffff59fff5b0, 1004b98b8, ffffffffffef9490, ffffffff7a33a2b8, 4c) + b0 ffffffff7a20a1f0 getValues (0, ffffffff59fff5b0, 4c, 2, 1, 3) + 120 ffffffff7a213d08 debugLoop_run (ffffffff7a33a2b8, ffffffff7a20a0d0, 0, ffffffff7a339780, ffffffff59fff768, ffffffff59fff738) + 1a8 ffffffff7a22976c connectionInitiated (ffffffff5a303c10, 1280, 1, ffffffff7a339780, ffffffff7a33aa00, 1000) + ec ffffffff7a229a40 attachThread (800, ffffffffffefef68, ffffffff5a303c10, ffffffff7a339780, 10fd94, 101000) + 58 ffffffff7d0d745c void JvmtiAgentThread::call_start_function() (0, 10051a000, 12f000, ffffffff7db7445a, ffffffff7dfc15d8, ffffffff7a2299e8) + 1ec ffffffff7d5edda0 void JavaThread::thread_main_inner() (10051a000, ffffffff59fffaa8, 10051adb8, ffffffff7dfc15d8, ffffffff7e082fe9, 10051a200) + 260 ffffffff7d5edab8 void JavaThread::run() (10051a000, 2c00, ffffffff7e0ad450, 10051a200, ffffffff7dfc15d8, 5) + 400 ffffffff7d3685dc java_start (10051a000, 11b0a0, 11b000, ffffffff7e0834d1, ffffffff7dfc15d8, 10051be68) + 35c ffffffff7e8d8558 _lwp_start (0, 0, 0, 0, 0, 0) The following extra tracing points to the target java method: debugee.stdout> MY_TRACE: TYPE_MISMATCH 5: dep: 0, idx: 2, _type: 12, valp->type(): 10 debugee.stdout> MY_TRACE: method: java/lang/invoke/MethodTypeForm:canonicalize(Ljava/lang/Class;I)Ljava/lang/Class; The method java/lang/invoke/MethodTypeForm:canonicalize(Ljava/lang/Class;I)Ljava/lang/Class; has a second slot that is the local variable "Class<?> ct": static Class<?> canonicalize(Class<?> t, int how) { Class<?> ct; The GetLocalObject is called from the JDWP function in StackFrameImpl.c : writeVariableValue(JNIEnv *env, PacketOutputStream *out, jthread thread, FrameNumber fnum, jint slot, jbyte typeKey) { jvmtiError error; jvalue value; if (isObjectTag(typeKey)) { WITH_LOCAL_REFS(env, 1) { error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalObject) (gdata->jvmti, thread, fnum, slot, &value.l); which is called from the JDWP function in StackFrameImpl.c : getValues(PacketInputStream *in, PacketOutputStream *out) { JNIEnv *env; int i; jdwpError serror; jthread thread; FrameID frame; jint variableCount; env = getEnv(); thread = inStream_readThreadRef(env, in); if (inStream_error(in)) { return JNI_TRUE; } frame = inStream_readFrameID(in); if (inStream_error(in)) { return JNI_TRUE; } variableCount = inStream_readInt(in); if (inStream_error(in)) { return JNI_TRUE; } /* * Validate the frame id */ serror = validateThreadFrame(thread, frame); if (serror != JDWP_ERROR(NONE)) { outStream_setError(out, serror); return JNI_TRUE; } (void)outStream_writeInt(out, variableCount); for (i = 0; (i < variableCount) && !outStream_error(out); i++) { jint slot; jbyte typeKey; FrameNumber fnum; slot = inStream_readInt(in); if (inStream_error(in)) break; typeKey = inStream_readByte(in); if (inStream_error(in)) break; fnum = getFrameNumber(frame); serror = writeVariableValue(env, out, thread, fnum, slot, typeKey); if (serror != JDWP_ERROR(NONE)) { outStream_setError(out, serror); break; } } return JNI_TRUE; } It seems to me that the getValues() gets correct information about the local variable frame or slot as it correctly identifies the slot#2 as an object type.
14-06-2014

Vladimir, Yes. Recently, I was able to reproduce the issue a couple of times, and then, it stopped to reproduce for many runs. Not sure, maybe it'd be good enough to use the same seed or something like that. It will help if you give me a crafted stand-alone testcase. Thank you for suggesting it!
03-06-2014

Serguei, do you mean the main obstacle for fixing this bug is it's hard to reproduce it with existing tests? I can help crafting stand-alone test case then.
03-06-2014

[To Vladimir Ivanov] There are cascading dependencies between several bugs. It makes it hard to reproduce the issues as they shadow each other. For instance, this one is blocked by: https://bugs.openjdk.java.net/browse/INTJDK-7611532 JSR 292: Breakpoint is not triggered in compiled code invoked via MethodHandle I hope, we will eventually resolve them one-by-one. At the moment, the most basic part is the test issue above (I've just moved it from the hotspot/jvmti category to the qe_test/hotspot). I'd try to fix it myself but not sure my understanding of the original test design is correct. So, let's wait for comments from Kirill.
03-06-2014

Chris, I will put a priority on this one (if any other urgency won't come up). It is on my list to fix anyway.
23-05-2014

[~sspitsyn], are you working on this one?
22-05-2014

Frequently hit this assert when debugging JSR292 code with fastdebug build (both 8 & 9, macos). What are the estimates when it can be fixed? It severely hinders development activities (at least, mine).
16-03-2014

Happened to me while debugging with an unmodified fastdebug, built on my computer 2013-11-22 (WIndows). Attaching hs_err + minidump
05-12-2013

8-defer-request: This bug is blocked on JDK-8017519. This test failure is currently hard to reproduce because it is blocked by the JDK-8017519. Until JDK-8017519 is fixed, this bug can't be fixed. Defer to a JDK8 update release. There is not much time to fix the JDK-8017519 in JDK 8, so that not time is left for the bug bug that depends on that fix. Also, it is possible that this issue is not reproducible anymore. But it is hard to prove until the JDK-8017519 is fixed.
07-10-2013

I can not reproduce this issue anymore.
07-10-2013

I'm in the middle of investigation. I'll defer to 8-pool when it is clear I'm running out of time. Why is this important to you? There are 3 more jsr-292 related JVMTI bugs on my plate. Do you want the same for them? Vladimir explained why, deferring now. The SVC team use tbd_minor.
13-09-2013

Serguei, will this fix make it into hs25? If not, can you defer to 8-pool?
12-09-2013

Yes. I forgot to tell this: enum BasicType { T_BOOLEAN = 4, T_CHAR = 5, T_FLOAT = 6, T_DOUBLE = 7, T_BYTE = 8, T_SHORT = 9, T_INT = 10, T_LONG = 11, T_OBJECT = 12,
27-08-2013

Are the types you print BasicTypes? requested type: 6, actual type: 10
27-08-2013

I've added a type checking code into the JVMTI internal function VM_GetOrSetLocal::doit(). This code returns the error JVMTI_ERROR_TYPE_MISMATCH if there is a local variable type mismatch between the expected and actual variable slot type. There are many type mismatches like the following: debugee.stdout> JVMTI GetLocal: Type mismatch: slot: 2, requested type: 6, actual type: 10 debugee.stdout> JVMTI GetLocal: Type mismatch: slot: 2, requested type: 12, actual type: 10 debugee.stdout> JVMTI GetLocal: Type mismatch: slot: 1, requested type: 11, actual type: 10 debugee.stdout> JVMTI GetLocal: Type mismatch: slot: 0, requested type: 11, actual type: 10 With that code in place we get many of the following exceptions: debugee.stdout> JVMTI GetLocal: Type mismatch: slot: 0, requested type: 11, actual type: 10 # ERROR: Exception when getting stack trace # ERROR: com.sun.jdi.InconsistentDebugInfoException # ERROR: at com.sun.tools.jdi.JDWPException.toJDIException(JDWPException.java:61) # ERROR: at com.sun.tools.jdi.StackFrameImpl.getValues(StackFrameImpl.java:241) # ERROR: at vm.mlvm.share.jdi.JDIBreakpointTest.getStackTraceStr(JDIBreakpointTest.java:432) # ERROR: at vm.mlvm.share.jdi.JDIBreakpointTest.run(JDIBreakpointTest.java:242) # ERROR: at vm.mlvm.share.MlvmTest.runMlvmTest(MlvmTest.java:225) # ERROR: at vm.mlvm.share.MlvmTest.launch(MlvmTest.java:141) # ERROR: at vm.mlvm.share.MlvmTest.launch(MlvmTest.java:106) # ERROR: at vm.mlvm.share.jdi.JDIBreakpointTest.main(JDIBreakpointTest.java:492) Without type checking code the original assertion is fired because of the type mismatch reason. Now, I wonder how it happens that the JDWP agent (libjdwp.so) makes all these incorrect calls to the JVMTI GetLocal<TYPE> functions. This is a relevant jdwp agent stack trace with the call to GetLocalObject(): ----------------- lwp# 7 / thread# 7 -------------------- ff08e7a0 ___lwp_cond_wait (1dba50, 1dba38, ffffffff, ff0755e0, fece41bc, 13aec0) + 8 fe1e9938 void os::PlatformEvent::park() (1dba00, e2400, 0, fe9fb070, fea494fd, fec7abc4) + 158 fe16b9d0 int Monitor::IWait(Thread*,long long) (4ac58, 1dac00, ffd80c7b, fece41d0, ffffffff, 4ac6c) + fc fe16d0f4 bool Monitor::wait(bool,long,bool) (4ac58, 1dac00, 0, fed170d8, fe9fc783, fec7abc4) + 534 fe4e9a08 void VMThread::execute(VM_Operation*) (b1e3f5e8, fed12fd8, 1, fec7abc4, 0, 1dac00) + 1fc fdf5887c jvmtiError JvmtiEnv::GetLocalObject(JavaThread*,int,int,_jobject**) (1dac00, 4c400, 0, 2, b1e3f780, 7a400) + 4c fdeb91b0 jvmti_GetLocalObject (b3c00, b2204988, 0, 2, b1e3f780, b1e3f6d8) + 524 fd0b8d18 writeVariableValue (1dad5c, b1e3f860, 2efd30, 0, 2, 4c) + a4 fd0b9908 getValues (b1e3f9c0, b1e3f860, 0, 2efd30, 1dad5c, 2) + 194 fd0c3304 debugLoop_run (400, fd0f7ac0, fd0b9774, fd0f75dc, b1e3f9e0, b1e3f9c0) + 1b4 fd0d855c connectionInitiated (fccb3020, 0, fd0f75dc, 1, 9d8, fd0f7fb4) + f4 fd0d8824 attachThread (400, fd0f75dc, fccb3020, fd0e6764, fffef188, 10c00) + 58 fdf91364 void JvmtiAgentThread::call_start_function() (1ffc, 6, fed170d4, 46970, 0, 0) + 208 fe411068 void JavaThread::thread_main_inner() (1dac00, b1e3fba4, 1db1e8, fec7abc4, fece4626, 1dad44) + 274 fe410d78 void JavaThread::run() (1dac00, 69800, 1, fec7abc4, 1dad44, 128800) + 43c fe1d9d98 java_start (1dac00, 2, 1dbf48, 236c00, fec7abc4, fea43e90) + 16c ff08a9c8 _lwp_start (0, 0, 0, 0, 0, 0)
27-08-2013

Let's reassign it to me.
15-07-2013

Christian, I did not work on this one yet.
15-07-2013

Serguei, any news on this one?
15-07-2013

Chris, let me look at it. The GetOrSetLocal is a JVMTI code. But this issue looks familiar, somebody recently integrated a fix related to a similar assert.
13-06-2013

Serguei, does that issue fall into your area?
13-06-2013

Currently there are a lot of JVMTI and JDI problems with 292. Serguei is working on most of them. I will have a look at this one, though.
06-06-2013

Looks like 292 and jdi interaction, which I believe the compiler team is working on.
07-05-2013