jatovm / jato

Jato, an open source implementation of the JVM
http://www.jatovm.org/
Other
153 stars 30 forks source link

Exceptions don't work from in dynamic proxy classes #16

Open penberg opened 13 years ago

penberg commented 13 years ago

$ cat DynamicProxyTest.java import java.lang.reflect.*;

public class DynamicProxyTest { public static void main(String[] args) { InvocationHandler handler = new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { throw new RuntimeException("hello"); } }; Runnable r = (Runnable) Proxy.newProxyInstance(Runnable.class.getClassLoader(), new Class[] { Runnable.class }, handler); r.run(); } }

With OpenJDK:

$ java DynamicProxyTest Exception in thread "main" java.lang.RuntimeException: hello at DynamicProxyTest$1.invoke(DynamicProxyTest.java:7) at $Proxy0.run(Unknown Source) at DynamicProxyTest.main(DynamicProxyTest.java:11)

With Jato:

$ jato DynamicProxyTest [main] SIGSEGV at EIP 0806a35f while accessing memory address 0000e14b. [main] Registers: [main] eax: 00000000 ebx: 08387410 ecx: b7455f8c edx: 00000000 [main] esi: 0000e0ff edi: a753384d ebp: bfb70e04 esp: bfb70ddc [main] Code: f3 74 68 83 7b 20 01 75 22 83 7e 20 01 75 58 83 ec 0c 53 e8 74 ff ff ff 89 1c 24 89 c7 e8 6a ff ff ff 89 fb 83 c4 10 89 c6 eb d4 <8b> 46 4c 85 c0 75 04 31 ff eb 2c 52 52 50 53 e8 a6 ff ff ff 83 [main] Native and Java stack trace: [main] [<0806a35f>] native : vm_class_is_assignable_from+46 (/home/penberg/src/jato/vm/class.c:1253) [main] [<0806a372>] native : vm_class_is_assignable_from+59 (/home/penberg/src/jato/vm/class.c:1253) [main] [<0805eec2>] native : throw_from_jit+53 (/home/penberg/src/jato/jit/exception.c:363) [main] [<0807867a>] native : throw_exception+32 (/home/penberg/src/jato/sys/linux-x86/exception.c:51) [main] [] jit : $Proxy0.run(Unknown Source) [main] [] jit : DynamicProxyTest.main(DynamicProxyTest.java:11) [main] [<0805ce05>] native : do_main_class+12c (/home/penberg/src/jato/vm/jato.c:1037) [main] [<0805d3ba>] native : jato(main+0x55f) [0x805d3ba] [main] [] native : signal_bh_trampoline+af3e8c5a (arch/x86/signal-bh.S:41) [main] [<0805bd50>] native : jato() [0x805bd50] Aborted

tgrabiec commented 13 years ago

This is caused by an incorrect resolving of non-empty entry stack in exception handler block when that block is preceded by another block which falls through to the exception handler. In other words if we have basic blocks like this: A (eh) -> B (eh) and throw to B then B will try to extract the exception from a temporary to which A was supposed to spill, but since we didn't go through A it contains a junk value. One possible solution to this is to make mimic stack resolver always spill an exception from A to a cu->exception_spill_slot, which would be used if B wasn't reachable from any other block (see EXPR_EXCEPTION_REF)