JDK-8163969 : Cyclic interface initialization causes JVM crash
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 8u101,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2016-08-12
  • Updated: 2017-11-29
  • Resolved: 2016-09-21
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.
8u152Fixed 9 b140Fixed
Related Reports
Relates :  
Relates :  
JRE version: Java(TM) SE Runtime Environment (8.0_101-b13) (build 1.8.0_101-b13)

Microsoft Windows [Version 6.1.7601]

Cyclic Interface initialization with exceptions causes an reproducible core dump.

Background Info: I'm a developer of the JaCoCo code coverage library. While preparing test cases for cyclic Interface initialization I encountered this issue and isolated a simple reproducer.



Compile and start the source code below. Also available here: https://gist.github.com/marchof/c0ac04a2abb4b163bf410e8018a72cb7


Proper exception handling


JVM crash
# A fatal error has been detected by the Java Runtime Environment:
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000006fb01b55, pid=5184, tid=0x000000000000453c
# JRE version: Java(TM) SE Runtime Environment (8.0_101-b13) (build 1.8.0_101-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# V  [jvm.dll+0x201b55]
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp

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

Current thread (0x00000000001ee800):  JavaThread "main" [_thread_in_vm, id=17724, stack(0x0000000002050000,0x0000000002150000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x0000000000000000

RAX=0x0000000000000000, RBX=0x00000000001ee800, RCX=0x0000000000000000, RDX=0x0000000000000000
RSP=0x000000000214ede0, RBP=0x000000000214ee69, RSI=0x0000000000000005, RDI=0x00000000001ee800
R8 =0x00000000001ee800, R9 =0x0000000060cd0000, R10=0x0000000000000000, R11=0x00000007c0060400
R12=0x0000000000000000, R13=0x0000000018f80290, R14=0x000000000214f210, R15=0x00000000001ee800
RIP=0x000000006fb01b55, EFLAGS=0x0000000000010202

Top of Stack: (sp=0x000000000214ede0)
0x000000000214ede0:   00000000001ee800 000000000214ee89
0x000000000214edf0:   0000000000000000 00000000001ef6e8
0x000000000214ee00:   0000000001dc2620 000000000214ee20
0x000000000214ee10:   00000000001ee800 00000000001ee800
0x000000000214ee20:   0000000781e27a58 0000000781e277d0
0x000000000214ee30:   0000000000000000 0000000001d7c970
0x000000000214ee40:   0000000001d7c9c0 0000000001d7cb50
0x000000000214ee50:   0000000001d7b034 0000000001d7b050
0x000000000214ee60:   ffffffff00000004 000000006fa10101
0x000000000214ee70:   00000000001ef2b0 000000000214ee20
0x000000000214ee80:   000000000214ee68 0000000800000002
0x000000000214ee90:   0000f9edefabc301 0000000000000041
0x000000000214eea0:   0000f9edefabc952 00000000001ee800
0x000000000214eeb0:   0000000000000005 00000000001ee800
0x000000000214eec0:   0000000000000000 000000006fb3cdb0
0x000000000214eed0:   0000000000000000 00000000001ee800 

Instructions: (pc=0x000000006fb01b55)
0x000000006fb01b35:   8b 5c 24 30 48 83 c4 20 5f c3 cc 48 89 4c 24 08
0x000000006fb01b45:   55 53 56 57 48 8d 6c 24 c1 48 81 ec c8 00 00 00
0x000000006fb01b55:   48 8b 01 49 8b f0 0f b6 fa 48 8b 18 48 8b c3 83
0x000000006fb01b65:   e0 07 48 83 f8 05 0f 85 26 01 00 00 48 f7 c3 80 

Register to memory mapping:

RAX=0x0000000000000000 is an unknown value
RBX=0x00000000001ee800 is a thread
RCX=0x0000000000000000 is an unknown value
RDX=0x0000000000000000 is an unknown value
RSP=0x000000000214ede0 is pointing into the stack for thread: 0x00000000001ee800
RBP=0x000000000214ee69 is pointing into the stack for thread: 0x00000000001ee800
RSI=0x0000000000000005 is an unknown value
RDI=0x00000000001ee800 is a thread
R8 =0x00000000001ee800 is a thread
R9 =0x0000000060cd0000 is an unknown value
R10=0x0000000000000000 is an unknown value
R11=0x00000007c0060400 is pointing into metadata
R12=0x0000000000000000 is an unknown value
R13=0x0000000018f80290 is pointing into metadata
R14=0x000000000214f210 is pointing into the stack for thread: 0x00000000001ee800
R15=0x00000000001ee800 is a thread

Stack: [0x0000000002050000,0x0000000002150000],  sp=0x000000000214ede0,  free space=1019k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [jvm.dll+0x201b55]
V  [jvm.dll+0x23cdb0]
V  [jvm.dll+0x107fea]
V  [jvm.dll+0x10d227]
V  [jvm.dll+0x10d191]
V  [jvm.dll+0x114f23]
V  [jvm.dll+0x115115]
V  [jvm.dll+0xbb82d]
C  0x0000000002445327

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  JvmCrash.main([Ljava/lang/String;)V+0
v  ~StubRoutines::call_stub

---------------  P R O C E S S  ---------------

Java Threads: ( => current thread )
  0x000000001a9fa000 JavaThread "Service Thread" daemon [_thread_blocked, id=16376, stack(0x000000001b670000,0x000000001b770000)]
  0x000000001a97b000 JavaThread "C1 CompilerThread2" daemon [_thread_blocked, id=7620, stack(0x000000001b470000,0x000000001b570000)]
  0x000000001a979800 JavaThread "C2 CompilerThread1" daemon [_thread_blocked, id=12668, stack(0x000000001b280000,0x000000001b380000)]
  0x000000001a972800 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=16892, stack(0x000000001b010000,0x000000001b110000)]
  0x0000000019578800 JavaThread "Attach Listener" daemon [_thread_blocked, id=3156, stack(0x000000001ada0000,0x000000001aea0000)]
  0x0000000019576000 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=13616, stack(0x000000001aee0000,0x000000001afe0000)]
  0x000000001955c000 JavaThread "Finalizer" daemon [_thread_blocked, id=14320, stack(0x000000001a780000,0x000000001a880000)]
  0x0000000019515000 JavaThread "Reference Handler" daemon [_thread_blocked, id=18104, stack(0x000000001a5f0000,0x000000001a6f0000)]
=>0x00000000001ee800 JavaThread "main" [_thread_in_vm, id=17724, stack(0x0000000002050000,0x0000000002150000)]

Other Threads:
  0x000000001950d000 VMThread [stack: 0x000000001a4a0000,0x000000001a5a0000] [id=14356]
  0x000000001aa18800 WatcherThread [stack: 0x000000001b780000,0x000000001b880000] [id=12656]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

 PSYoungGen      total 56320K, used 4672K [0x0000000781a00000, 0x0000000785880000, 0x00000007c0000000)
  eden space 48640K, 9% used [0x0000000781a00000,0x0000000781e90080,0x0000000784980000)
  from space 7680K, 0% used [0x0000000785100000,0x0000000785100000,0x0000000785880000)
  to   space 7680K, 0% used [0x0000000784980000,0x0000000784980000,0x0000000785100000)
 ParOldGen       total 128512K, used 0K [0x0000000704e00000, 0x000000070cb80000, 0x0000000781a00000)
  object space 128512K, 0% used [0x0000000704e00000,0x0000000704e00000,0x000000070cb80000)
 Metaspace       used 2814K, capacity 4488K, committed 4864K, reserved 1056768K
  class space    used 309K, capacity 388K, committed 512K, reserved 1048576K

Card table byte_map: [0x00000000117e0000,0x0000000011dc0000] byte_map_base: 0x000000000dfb9000

Marking Bits: (ParMarkBitMap*) 0x000000007011a6d0
 Begin Bits: [0x0000000012810000, 0x00000000156d8000)
 End Bits:   [0x00000000156d8000, 0x00000000185a0000)

Polling page: 0x00000000001c0000

CodeCache: size=245760Kb used=1235Kb max_used=1235Kb free=244524Kb
 bounds [0x0000000002420000, 0x0000000002690000, 0x0000000011420000]
 total_blobs=320 nmethods=85 adapters=148
 compilation: enabled

Compilation events (10 events):
Event: 0.515 Thread 0x000000001a97b000 nmethod 78 0x000000000254e8d0 code [0x000000000254ea20, 0x000000000254eb50]
Event: 0.515 Thread 0x000000001a97b000   79       3       java.util.BitSet::checkInvariants (111 bytes)
Event: 0.515 Thread 0x000000001a97b000 nmethod 79 0x000000000254ebd0 code [0x000000000254ed20, 0x000000000254eeb0]
Event: 0.516 Thread 0x000000001a97b000   80       3       java.lang.String::substring (79 bytes)
Event: 0.516 Thread 0x000000001a97b000 nmethod 80 0x000000000254ef10 code [0x000000000254f0c0, 0x000000000254f578]
Event: 0.516 Thread 0x000000001a97b000   81       3       java.lang.String::endsWith (17 bytes)
Event: 0.517 Thread 0x000000001a97b000 nmethod 81 0x000000000254f790 code [0x000000000254f900, 0x000000000254fb28]
Event: 0.517 Thread 0x000000001a97b000   82       1       java.net.URL::getPort (5 bytes)
Event: 0.517 Thread 0x000000001a97b000 nmethod 82 0x000000000254fc50 code [0x000000000254fda0, 0x000000000254feb0]
Event: 0.518 Thread 0x000000001a97b000   84  s!   3       sun.misc.URLClassPath::getLoader (197 bytes)

GC Heap History (0 events):
No events

Deoptimization events (0 events):
No events

Internal exceptions (8 events):
Event: 0.257 Thread 0x00000000001ee800 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.defineClass(Ljava/lang/String;[BII)Ljava/lang/Class; name or signature does not match> (0x0000000781a07cc0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\s���2o���!m���?
Event: 0.257 Thread 0x00000000001ee800 Exception <a 'java/lang/NoSuchMethodError': Method sun.misc.Unsafe.prefetchRead(Ljava/lang/Object;J)V name or signature does not match> (0x0000000781a07fa8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\T���"������1���?
Event: 0.409 Thread 0x00000000001ee800 Exception <a 'java/util/zip/ZipException'> (0x0000000781a91950) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jni.cpp, line 709]
Event: 0.410 Thread 0x00000000001ee800 Exception <a 'java/security/PrivilegedActionException'> (0x0000000781a91bf0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.410 Thread 0x00000000001ee800 Exception <a 'java/security/PrivilegedActionException'> (0x0000000781a91e00) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.434 Thread 0x00000000001ee800 Exception <a 'java/security/PrivilegedActionException'> (0x0000000781aae248) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.434 Thread 0x00000000001ee800 Exception <a 'java/security/PrivilegedActionException'> (0x0000000781aae458) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\prims\jvm.cpp, line 1386]
Event: 0.520 Thread 0x00000000001ee800 Exception <a 'java/lang/ExceptionInInitializerError'> (0x0000000781e27a58) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u101\7261\hotspot\src\share\vm\oops\instanceKlass.cpp, line 969]

Events (10 events):
Event: 0.509 loading class JvmCrash$1
Event: 0.509 loading class JvmCrash$1 done
Event: 0.511 loading class JvmCrash$Target
Event: 0.511 loading class JvmCrash$Target done
Event: 0.514 loading class JvmCrash$Base
Event: 0.514 loading class JvmCrash$Base done
Event: 0.517 loading class JvmCrash$Base$1
Event: 0.517 loading class JvmCrash$Base$1 done
Event: 0.519 loading class java/lang/ExceptionInInitializerError
Event: 0.520 loading class java/lang/ExceptionInInitializerError done

Dynamic libraries:
0x000000013f040000 - 0x000000013f077000 	C:\devtools\jdk1.8.0_101\bin\javaw.exe
0x0000000077b00000 - 0x0000000077caa000 	C:\Windows\SYSTEM32\ntdll.dll
0x00000000779e0000 - 0x0000000077aff000 	C:\Windows\system32\kernel32.dll
0x000007fefd8a0000 - 0x000007fefd90a000 	C:\Windows\system32\KERNELBASE.dll
0x000007fefef60000 - 0x000007feff03b000 	C:\Windows\system32\ADVAPI32.dll
0x000007feff680000 - 0x000007feff71f000 	C:\Windows\system32\msvcrt.dll
0x000007feff720000 - 0x000007feff73f000 	C:\Windows\SYSTEM32\sechost.dll
0x000007fefeba0000 - 0x000007fefeccd000 	C:\Windows\system32\RPCRT4.dll
0x00000000778e0000 - 0x00000000779da000 	C:\Windows\system32\USER32.dll
0x000007feff040000 - 0x000007feff0a7000 	C:\Windows\system32\GDI32.dll
0x000007fefeb30000 - 0x000007fefeb3e000 	C:\Windows\system32\LPK.dll
0x000007feff2e0000 - 0x000007feff3aa000 	C:\Windows\system32\USP10.dll
0x000007fefbed0000 - 0x000007fefc0c4000 	C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.18837_none_fa3b1e3d17594757\COMCTL32.dll
0x000007feff8b0000 - 0x000007feff921000 	C:\Windows\system32\SHLWAPI.dll
0x000007fefeb40000 - 0x000007fefeb6e000 	C:\Windows\system32\IMM32.DLL
0x000007feff740000 - 0x000007feff849000 	C:\Windows\system32\MSCTF.dll
0x0000000060cd0000 - 0x0000000060da2000 	C:\devtools\jdk1.8.0_101\jre\bin\msvcr100.dll
0x000000006f900000 - 0x000000007019a000 	C:\devtools\jdk1.8.0_101\jre\bin\server\jvm.dll
0x000007fef7e60000 - 0x000007fef7e69000 	C:\Windows\system32\WSOCK32.dll
0x000007feff0b0000 - 0x000007feff0fd000 	C:\Windows\system32\WS2_32.dll
0x000007fefeb90000 - 0x000007fefeb98000 	C:\Windows\system32\NSI.dll
0x000007fef9570000 - 0x000007fef95ab000 	C:\Windows\system32\WINMM.dll
0x000007fefc960000 - 0x000007fefc96c000 	C:\Windows\system32\VERSION.dll
0x0000000077cc0000 - 0x0000000077cc7000 	C:\Windows\system32\PSAPI.DLL
0x000000006f0e0000 - 0x000000006f0ef000 	C:\devtools\jdk1.8.0_101\jre\bin\verify.dll
0x0000000069e90000 - 0x0000000069eb9000 	C:\devtools\jdk1.8.0_101\jre\bin\java.dll
0x000000006e820000 - 0x000000006e836000 	C:\devtools\jdk1.8.0_101\jre\bin\zip.dll
0x000007fefdc40000 - 0x000007fefe9ca000 	C:\Windows\system32\SHELL32.dll
0x000007feffc00000 - 0x000007feffe03000 	C:\Windows\system32\ole32.dll
0x000007fefd880000 - 0x000007fefd88f000 	C:\Windows\system32\profapi.dll
0x000007fef2b60000 - 0x000007fef2c85000 	C:\Windows\system32\dbghelp.dll

VM Arguments:
jvm_args: -Dfile.encoding=UTF-8 
java_command: JvmCrash
java_class_path (initial): D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.slf4j_1.7.7.201606010400\jars\slf4j-log4j12-1.7.7.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.slf4j_1.7.7.201606010400\jars\slf4j-api-1.7.7.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.slf4j_1.7.7.201606010400\jars\jul-to-slf4j-1.7.7.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.apache.commons.configuration_1.9.0.201606010400\jars\commons-configuration-1.9.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.apache.commons.lang_2.6.0.201606010400\jars\commons-lang-2.6.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.mozilla.javascript_1.6.5.201606010400\jars\js-1.6R5.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.joda.time_1.6.2.201606010400\jars\joda-time-1.6.2.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\com.tibco.tibrv_8.4.2.201606010400\jars\tibrvnative-8.4.2.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.apache.log4j_1.2.17.201606010400\jars\log4j-1.2.17.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.apache.commons.net_3.1.0.201606010400\jars\commons-net-3.1.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.eclipse.osgi_3.8.2.v20130124-134944.jar;D:\sbbdev\eclipse-ws-rcs-trunk\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.apache.commons.collections_3.2.2.201606010400\jars\commons-collections-3.2.2.jar;D:\sbbdev\eclipse-ws-rcs-trunk\RCS_D_COMMON\bin;D:\sbbdev\eclipse-ws-rcs-trunk\ch.sbb.rcsd.transfer.common\
Launcher Type: SUN_STANDARD

Environment Variables:
PATH=C:/Program Files/Java/jre1.8.0_65/bin/server;C:/Program Files/Java/jre1.8.0_65/bin;C:/Program Files/Java/jre1.8.0_65/lib/amd64;C:\Program Files\tibco\tibrv\8.4\bin;C:\Program Files\tibco\tibrv\8.4\bin;C:\ProgramData\Oracle\Java\javapath;C:\devtools\oracle\client-11.2.0;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\AutoInst\Tools;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x64;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\Microsoft Application Virtualization Client;C:\Program Files\TortoiseSVN\bin;C:\devtools\jdk1.7.0_55\jre\bin;C:\devtools\sliksvn-1.8.8\bin;C:\devtools\oracle\product\11.2.0\client_1\bin;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\OpenText\Viewer\bin;C:\devtools\nodejs-4.2.6\;C:\Users\ue30465\.babun;c:\devtools\babun\.babun;C:\Users\ue30465\AppData\Roaming\npm;C:\devtools\rcspaeckli-201603041401;
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 69 Stepping 1, GenuineIntel

---------------  S Y S T E M  ---------------

OS: Windows 7 , 64 bit Build 7601 (6.1.7601.23392)

CPU:total 4 (2 cores per cpu, 2 threads per core) family 6 model 69 stepping 1, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, rtm, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2

Memory: 4k page, physical 12262924k(5171508k free), swap 24523992k(16816712k free)

vm_info: Java HotSpot(TM) 64-Bit Server VM (25.101-b13) for windows-amd64 JRE (1.8.0_101-b13), built on Jun 22 2016 01:21:29 by "java_re" with MS VC++ 10.0 (VS2010)

time: Fri Aug 12 14:03:06 2016
elapsed time: 0 seconds (0d 0h 0m 0s)

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
 * This snippet crashes with
 *   - Java(TM) SE Runtime Environment (8.0_101-b13) (build 1.8.0_101-b13)
public class JvmCrash {

	interface Base {
		static final Object CONST = new Target(){}.someMethod();
		default void important() {
			// Super interfaces with default methods get initialized (JLS 12.4.1)
	interface Target extends Base {
		default Object someMethod() {
			throw new RuntimeException();

	public static void main(String[] args) {
		new Target() {};


---------- END SOURCE ----------

Don't test wired corner cases ;-)

Thank you to the developer of the JaCoCo code coverage library for finding this bug.

As it stands step 7 does not trigger initialization of Base while Initializing Target, whilst initializing the inner class. So if the expectation is that Base is initialized then step 7 needs to be rewritten! Taking a little side excursion into a different initialization sequence, just for interfaces, is very confusing and seems unnecessarily fragile and error prone as this bug shows. This bug is happening because contrary to what step 7 currently requires, that little side excursion does not go back to step 1 for the interface. If it did and we marked Target as being initialized, then Base could not mark Target as fully initialized. Base would fail to initialize due to the exception and would be marked erroneous, and that would cause the initialization of Target to fail and then the initialization of the inner class to fail. But because initialize_super_interfaces does not mark this_k as being initialized we hit this bug.

I found the rule for initializing super interfaces only if you start with initializing a class rather than for initializing an interface to be confusing as well. The rationale explained to me was that we wanted to minimize the surprise factor for customers in terms of order of initialization. Despite the fact that the specification allows for lazy initialization triggered by lazy linking, for some customer applications, the order of initialization performed matters deeply and so the goal here was to minimize the changes in initialization order, only initializing super interfaces which contain default methods, which implies that the subclass might inherit a default method and need to have the initialization performed before executing that default method. Since interfaces can not be instantiated, initialization of an interface (not in response to initializing a subclass) by itself doesn't need to trigger super interface initialization. I worked closely with Dan and Paul Sandoz to reach agreement on the expected order of interface initialization when working on 8034275.See TestInterfaceOrder from that fix. Specifically, initialization of interface I, which is a direct super interface of another interface, but not a direct super interface of any class - does get triggered by initialization of an indirect subclass, and specifically gets initialized first. So if the JLS 12.4.2 wording needs to be clearer in its Step 7 description to describe that - let's work with Dan on improved wording. See also JVMS 5.5 " If C is an interface that declares a non-abstract, non-static method, the initialization of a class that implements C directly or indirectly." Note that TestInterfaceOrder defines the agreed upon behavior when initializing super interfaces that do define default methods, including the order of their initialization. The test TestInterfaceInit catches my mistake in this earlier implementation, i.e. that we should only initialize interfaces which declare default methods. I did not back port that fix to JDK8 since it was a behavior change. I did not walk this one through the spec folks so it doesn't "define' any agreed upon behavior, it just reflects Vladimir and my understanding of the specification. I think this would be a good time to write a test that covers various examples of errors during superclass and super interface initialization and to work with Dan Smith and if he has time, Paul Sandoz, to ensure that the examples match the expected behavior and if we need any clarifications in the specification, to ask for them. hope this helps

new Target() {} defines an anonymous class that implements the Target interface. I've started to respond to this three times now and each time have changed my mind about what is wrong :) I agree with the analysis that the initialization process for interfaces is wrong, but I don't agree with the suggested fix - or at least not in the context of the current spec. I agree what is wrong is InstanceKlass::initialize_super_interfaces. It should not recursively call InstanceKlass::initialize_super_interfaces on each interface as that violates the JVMS: 7. Next, if C is a class rather than an interface, and its superclass has not yet been initialized, then let SC be its superclass and let SI1, ..., SIn be all superinterfaces of C (whether direct or indirect) that declare at least one non-abstract, non-static method. The order of superinterfaces is given by a recursive enumeration over the superinterface hierarchy of each interface directly implemented by C. For each interface I directly implemented by C (in the order of the interfaces array of C), the enumeration recurs on I's superinterfaces (in the order of the interfaces array of I) before returning I. For each S in the list [ SC, SI1, ..., SIn ], recursively perform this entire procedure for S. If necessary, verify and prepare S first. -- If we recursively apply "this entire procedure" to the first interface (Target in this case) then Target is NOT a class and so the rest of clause 7 does not apply to it. Hence we should not initialize Base while initializing Target. At step 7 of initialize_impl we should simply be doing: for each class K in super, implemented-interfaces-with-default-methods do K->initialize_impl() That said I think the specification is flawed as written because it appears to allow for an interface to be fully, successfully initialized, even though its super-interface may have failed initialization and is in the Erroneous state. That seems wrong to me, but the JVMS spec owner needs to make that decision.

I left out a couple of details above. We only recurse on the super_interfaces if the interface->has_default_methods() (meaning one of its interfaces declares a default method), and only initialize if it directly declares a default method. This is only if the entire initialization starts with a class, rather than an interface. It's a very odd distinction. Target is a direct interface of a class that is created by the anonymous class created in "new Target(){}", thanks for clarifying that. I'd created a real inner class in my test. So since Target has a declared default method, we initialize that. While initializing that, we look at Base. Base has a declared default method too, so we initialize that after starting to initialize target. >For each interface I directly implemented by C (in the order of the interfaces array of C), the enumeration recurs on I's superinterfaces (in the order of the interfaces array of I) before returning I. This bit seems to say that we _do_ recur on I's interfaces to initialize. But you are right, if it doesn't because it doesn't make any sense to have Target fully initialized before it's superinterface Base. It would be very wrong. But I think this says that you recur on interfaces only if the initialization begins with a class (which is what the code does). Oh, sorry above, I meant to add that I changed the code to only initiate the superclass initialization recursion if a class is being initialized (ie, if the initialization starts with a class). I still think this is a strange rule and would love to know the rationale behind it. One thing I didn't try is to initialize Target alone with a variable reference so it doesn't initialize Base. Target's initialization would succeed then the initialization of Base would then get an initialization exception, but not crash because Target is not in the process of being marked as Initialization failed. I'll try some more testing though because it seems like there are some non-sensical situations we can have here (or not, if the code works right).

In JLS 12.4.1: When a class is initialized, its superclasses are initialized (if they have not been previously initialized), as well as any superinterfaces (��8.1.5) that declare any default methods (��9.4.3) (if they have not been previously initialized). Initialization of an interface does not, of itself, cause initialization of any of its superinterfaces.

The root cause of this is that the interface initialization doesn't follow the standard protocol in initialize_impl. In there when a class/interface is being initialized, it checks for recursive initialization with the same thread(ok) or not(not ok) and marks the class as "being_initialized". In the function initialize_super_interfaces, the local interfaces are recursively initialized in behalf of the class passed in, but the class passed in hasn't been marked as being_initialized (or recursive initialization checked etc). In this test, there is a Target class with a base Base class. The Base class calls a function in Target class, which throws an exception. For some reason javac puts some Base$1 inner class to call Target.someMethod, but this isn't the interesting part. For the "new Target() {};" call, this creates an inner class to do the initialization (not sure why javac does this). When we call initialize_super_interfaces for the inner class, this recursively calls initialize_super_interfaces for Target, which then calls initialize() for Base through initialize_impl. Base is marked as "being initialized". The initialization for Base then tries to initialize Target for the someMethod call, the initialization for Target succeeds because when it calls Base->initialize_impl() that returns because it's already being initialized. Target is then marked as fully_initialized and the init_lock is removed for Target. Popping back to the initialize_super_interfaces finds that initialization of Base actually failed (the exception thrown) and tries to mark Target as initialization_failed, which it can't because Target is fully_initialized already. The root cause is that Target is trying to initialize super interfaces without going through the initialization protocol as implemented in initialize_impl. I have a fix for this that removes the special case for interface in initialize_impl, so that interfaces will call initialize for their local_interfaces if they declare default methods, and recursively initialize any local interfaces that has_default_methods(). Essentially, initializing an interface in initialize_impl will also call initialize_super_interfaces, not just classes. I'm not sure why this code was restricted to classes, ie, if there was a JVMLS rule about that. I couldn't find it. This fix fails the test added with JDK-8043275 though because the test expects the initialization of the interface L to not trigger initialization of the interfaces with default methods that L inherits, because L is an interface. But initializing L's interfaces through the normal initialize_impl protocol, causes initialization of the super interfaces that need it. I think the new behavior makes a lot of sense and is correct.

FYI, lock == NULL and _init_state == fully_initialized at oop InstanceKlass::init_lock()

Info from reporter : According to hg bisect result, it is caused by the fix of JDK-8043275

hg bisect logs from reporter

Introduced in 8u40-b13, most likely caused by JDK-8043275

Debug build shows: # To suppress the following error report, specify this argument # after -XX: or in .hotspotrc: SuppressErrorAt=/handles.hpp:74 # # A fatal error has been detected by the Java Runtime Environment: # # Internal Error (/scratch/dh198349/jdk9-hs/hotspot/src/share/vm/runtime/handles.hpp:74), pid=12196, tid=12197 # assert(_handle != __null) failed: resolving NULL handle # # JRE version: Java(TM) SE Runtime Environment (9.0) (fastdebug build 9-internal+0-2016-07-26-022658.daholme.jdk9-hs) # Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 9-internal+0-2016-07-26-022658.daholme.jdk9-hs, mixed mode, tiered, compressed oops, g1 gc, linux-amd64) # Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c" (or dumping to /export/users/dh198349/jdk9-hs/core.12196) --------------- T H R E A D --------------- Current thread (0x00007fc104019800): JavaThread "main" [_thread_in_vm, id=12197, stack(0x00007fc10d472000,0x00007fc10d57300 0)] Stack: [0x00007fc10d472000,0x00007fc10d573000], sp=0x00007fc10d571040, free space=1020k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0x16bef62] VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, vo id*, void*, char const*, int, unsigned long)+0x162 V [libjvm.so+0x16bfcdf] VMError::report_and_die(Thread*, char const*, int, char const*, char const*, __va_list_tag*)+0x2f V [libjvm.so+0xa93ffd] report_vm_error(char const*, int, char const*, char const*, ...)+0xdd V [libjvm.so+0x6acc36] BiasedLocking::revoke_and_rebias(Handle, bool, Thread*)+0x486 V [libjvm.so+0x15c1d3a] ObjectSynchronizer::notifyall(Handle, Thread*)+0xfa V [libjvm.so+0xdce4fd] InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle, InstanceKlass::ClassSt ate, Thread*)+0xed V [libjvm.so+0xdce63b] InstanceKlass::set_initialization_state_and_notify(InstanceKlass::ClassState, Thread*)+0x8b V [libjvm.so+0xdce84f] InstanceKlass::initialize_super_interfaces(instanceKlassHandle, Thread*) [clone .part.146]+0x1ef V [libjvm.so+0xdce7a1] InstanceKlass::initialize_super_interfaces(instanceKlassHandle, Thread*) [clone .part.146]+0x141 V [libjvm.so+0xdd191c] InstanceKlass::initialize_impl(instanceKlassHandle, Thread*) [clone .part.162]+0x61c V [libjvm.so+0xdd1d23] InstanceKlass::initialize_impl(instanceKlassHandle, Thread*)+0xf3 V [libjvm.so+0xdd1e15] InstanceKlass::initialize(Thread*)+0xc5 V [libjvm.so+0xdf61ab] InterpreterRuntime::_new(JavaThread*, ConstantPool*, int)+0x1cb j JvmCrash.main([Ljava/lang/String;)V+0

Below is the result == 7uxx - Not applicable 8u1 - Pass 8u33 - Pass 8u40 - Fail 8u102 - Fail 9 ea b-131 - Fail

This is an issue introduced in 8u40, below is the result 8u33 == -sh-4.1$ /opt/java/jdk1.8.0_33/bin/javac JvmCrash.java -sh-4.1$ /opt/java/jdk1.8.0_33/bin/java JvmCrash Exception in thread "main" java.lang.ExceptionInInitializerError at JvmCrash.main(JvmCrash.java:22) Caused by: java.lang.RuntimeException at JvmCrash$Target.someMethod(JvmCrash.java:17) at JvmCrash$Base.<clinit>(JvmCrash.java:8) ... 1 more == 8u40 == -sh-4.1$ /opt/java/jdk1.8.0_40/bin/javac JvmCrash.java -sh-4.1$ /opt/java/jdk1.8.0_40/bin/java JvmCrash # # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007fc83fec1d03, pid=19593, tid=140498039342848 # # JRE version: Java(TM) SE Runtime Environment (8.0_40-b27) (build 1.8.0_40-b27) # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.40-b25 mixed mode linux-amd64 compressed oops) # Problematic frame: # V [libjvm.so+0x320d03] BiasedLocking::revoke_and_rebias(Handle, bool, Thread*)+0x33 # # Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again # # An error report file with more information is saved as: # /home/fmatte/JI/9042792/hs_err_pid19593.log # # If you would like to submit a bug report, please visit: # http://bugreport.java.com/bugreport/crash.jsp # Aborted (core dumped) ==

further comment from JaCoCo - that this is also reproducible on latest JDK9 EA b131.