JDK-6271353 : Infinite recursion during handling of IllegalMonitorStateException
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 1.4.2_09
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_8
  • CPU: sparc
  • Submitted: 2005-05-17
  • Updated: 2014-12-15
  • Resolved: 2006-09-20
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 7
7Resolved
Related Reports
Duplicate :  
Relates :  
Description
The following test class SyncTest.java:

public class SyncTest
{
    public static Object lock = new Object();
    static int i = 0;
    void test() {
	synchronized(lock) {
	    i = 5;
	}
    }
}

produces these bytecodes for the method test():

--------
| test |
--------
010e  0000           access_flags:     
0110  000e           name:            "test"
0112  000b           descriptor:      "()V"
0114  0001           attributes_count: 1

0116  000c 00000049  Attribute "Code" len=73
011c  0001           max_stack:   1
011e  0003           max_locals:  3
0120  00000015       code_length: 21

0124  b2 0002           0 getstatic #2 "SyncTest" ("lock" "Ljava/lang/Object;")
0127  4c                3 astore_1
0128  2b                4 aload_1
0129  c2                5 monitorenter
012a  08                6 iconst_5
012b  b3 0003           7 putstatic #3 "SyncTest" ("i" "I")
012e  2b               10 aload_1
012f  c3               11 monitorexit
0130  a7 0008          12 goto 20
0133  4d               15 astore_2
0134  2b               16 aload_1
0135  c3               17 monitorexit
0136  2c               18 aload_2
0137  bf               19 athrow
0138  b1               20 return

0139  0002           exception_table_length: 2
      exception handler #1
013b  0006           start_pc:   6
013d  000c           end_pc:     12
013f  000f           handler_pc: 15
0141  0000           catch_type: 0 - Catches all exceptions.
      exception handler #2
0143  000f           start_pc:   15
0145  0012           end_pc:     18
0147  000f           handler_pc: 15
0149  0000           catch_type: 0 - Catches all exceptions.

==================================================================================

Notice that exception handler #2 defines an exception handler that designates itself as the handler for exceptions thrown within its own range.  Though this example cannot in of itself cause an IllegalMonitorStateException to be thrown, other examples using bytecode assemblers or JNI code can be manifactured to throw this exception.  For VMs that do not enforced structured locking (paired locks and unlocking), we can have a situation where the IllegalMonitorStateException is thrown while trying to execute the monitorexit bytecode if the object was not previously locked.  And based on the way the 1.4 javac generates code for the synthesized exception handler, we will end up catching the exception in exception handler #2 which then tries to do a monitorexit on the same object again.  This results in another IllegalMonitorStateException being thrown because the object is still not locked by the current thread.  This will happen perpetually resulting in what appears to be a hang.

This bug is similar to the case in CR 6271340, but this one does not involve a finally clause (i.e. no jsr/ret bytecodes), and can cause a real hang for some VM implementations.  Note that the VM spec says that VMs may, but are not required to, enforce structured locking.

###@###.### 2005-05-17 00:47:30 GMT