Duplicate :
|
|
Duplicate :
|
|
Duplicate :
|
Code generation for try{}finally{} generates a catch block around the implicitly generated catch-all clause that jsrs to the finally clause itself. This catch phrase names itself as the recipient! This is useless. More interestingly, the synchronized statement places a catch record around the monitorexit instruction so it can retry the instruction if there is an asynchronous exception. Infortunately, that catch record catches all, so an IllegalMonitorStateException will cause the VM to enter an infinite loop retrying the monitorexit instruction forever. frog$ cat -n Fbug.java 1 class Fbug { 2 int m; 3 4 void test(Fbug f, int m) { 5 try { 6 this.m = f.m; 7 } finally { 8 this.m = 0; 9 } 10 } 11 } frog$ javap -c Fbug Compiled from Fbug.java synchronized class Fbug extends java.lang.Object /* ACC_SUPER bit set */ { int m; Fbug(); void test(Fbug, int); } Method Fbug() 0 aload_0 1 invokespecial #1 <Method java.lang.Object()> 4 return Method void test(Fbug, int) 0 aload_0 1 aload_1 2 getfield #2 <Field int m> 5 putfield #2 <Field int m> 8 jsr 20 11 goto 29 14 astore_3 15 jsr 20 18 aload_3 19 athrow 20 astore 4 22 aload_0 23 iconst_0 24 putfield #2 <Field int m> 27 ret 4 29 return Exception table: from to target type 0 11 14 any 14 18 14 any frog$
|