Error instrumenting infinite loop
dwing4g opened this issue · comments
package test;
import java.util.concurrent.CompletableFuture;
import com.ea.async.Async;
public class TestAsync {
public static CompletableFuture<Void> test() {
for(;;) Async.await(new CompletableFuture<Void>());
}
public static void main(String[] args) {
Async.init();
}
}
java -cp ../lib/asm-debug-all-5.0.4.jar;. -javaagent:../lib/async-stub.jar test.TestAsync
java.lang.RuntimeException: Error instrumenting: test/TestAsync
at com.ea.async.instrumentation.Transformer.transform(Transformer.java:163)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
......
Caused by: java.lang.IllegalStateException
at org.objectweb.asm.MethodWriter.visitFrame(MethodWriter.java:659)
at org.objectweb.asm.tree.FrameNode.accept(FrameNode.java:148)
at org.objectweb.asm.tree.InsnList.accept(InsnList.java:162)
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:817)
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:727)
at org.objectweb.asm.tree.ClassNode.accept(ClassNode.java:412)
at com.ea.async.instrumentation.Transformer.transform(Transformer.java:337)
at com.ea.async.instrumentation.Transformer.transform(Transformer.java:153)
... 15 more
Thanks for the report. I'm looking into it.
Will this be fixed? how well is this project been maintained
The project is maintained and we recently introduced compatibility for JDK9/10.
I would like to take a look at this issue but unfortunately I haven't had time and as it's fairly easy to work around it's not a super high priority for us right now.
I'd welcome any contributions and I hope to have more time to dedicate to this project in the near future.
Thank you, I will try to catch up this, this is pretty cool
I think this is fixed, I tested with the following code,
`public static CompletableFuture test1() {
String value = Async.await(test2());
System.out.println(value);
String value1 = Async.await(test2());
System.out.println(value1);
for(;;) {
System.out.println(Async.await(test2()));
}
//return CompletableFuture.completedFuture(null);
}
public static CompletableFuture<String> test2() {
return CompletableFuture.completedFuture("value");
}`
and ea-async generates the following javabyte code for async$test1
` private static async$test1(java.util.concurrent.CompletableFuture arg0, java.lang.String arg1, java.lang.String arg2, java.io.PrintStream arg3, int arg4, java.lang.Object arg5) { //(Ljava/util/concurrent/CompletableFuture;Ljava/lang/String;Ljava/lang/String;Ljava/io/PrintStream;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
<localVar:index=0 , name=value , desc=Ljava/lang/String;, sig=null, start=L1, end=L2>
<localVar:index=1 , name=value1 , desc=Ljava/lang/String;, sig=null, start=L3, end=L2>
iload4 // reference to arg4
tableswitch
val: 0 -> L4
val: 1 -> L2
val: 2 -> L5
val: 3 -> L6
default -> L7
L4 {
invokestatic org/sonatype/mavenbook/App.test2()Ljava/util/concurrent/CompletableFuture;
dup
invokevirtual java/util/concurrent/CompletableFuture.isDone()Z
ifne L8
astore2 // reference to arg2
aload2 // reference to arg2
invokestatic java/util/function/Function.identity()Ljava/util/function/Function;
invokevirtual java/util/concurrent/CompletableFuture.exceptionally(Ljava/util/function/Function;)Ljava/util/concurrent/CompletableFuture;
aload2 // reference to arg2
aconst_null
aconst_null
aconst_null
sipush 1
invokedynamic java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; : apply(Ljava/util/concurrent/CompletableFuture;Ljava/lang/String;Ljava/lang/String;Ljava/io/PrintStream;I)Ljava/util/function/Function; (Ljava/lang/Object;)Ljava/lang/Object; org/sonatype/mavenbook/App.async$test1(Ljava/util/concurrent/CompletableFuture;Ljava/lang/String;Ljava/lang/String;Ljava/io/PrintStream;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture; (6) (Ljava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
invokevirtual java/util/concurrent/CompletableFuture.thenCompose(Ljava/util/function/Function;)Ljava/util/concurrent/CompletableFuture;
areturn
}
L8 {
invokevirtual java/util/concurrent/CompletableFuture.join()Ljava/lang/Object;
checkcast java/lang/String
astore0 // reference to arg0
}
L1 {
getstatic java/lang/System.out:java.io.PrintStream
aload0 // reference to arg0
invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V
}
L9 {
invokestatic org/sonatype/mavenbook/App.test2()Ljava/util/concurrent/CompletableFuture;
dup
invokevirtual java/util/concurrent/CompletableFuture.isDone()Z
ifne L10
astore2 // reference to arg2
aload2 // reference to arg2
invokestatic java/util/function/Function.identity()Ljava/util/function/Function;
invokevirtual java/util/concurrent/CompletableFuture.exceptionally(Ljava/util/function/Function;)Ljava/util/concurrent/CompletableFuture;
aload2 // reference to arg2
aload0 // reference to arg0
aconst_null
aconst_null
sipush 2
invokedynamic java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; : apply(Ljava/util/concurrent/CompletableFuture;Ljava/lang/String;Ljava/lang/String;Ljava/io/PrintStream;I)Ljava/util/function/Function; (Ljava/lang/Object;)Ljava/lang/Object; org/sonatype/mavenbook/App.async$test1(Ljava/util/concurrent/CompletableFuture;Ljava/lang/String;Ljava/lang/String;Ljava/io/PrintStream;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture; (6) (Ljava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
invokevirtual java/util/concurrent/CompletableFuture.thenCompose(Ljava/util/function/Function;)Ljava/util/concurrent/CompletableFuture;
areturn
}
L10 {
invokevirtual java/util/concurrent/CompletableFuture.join()Ljava/lang/Object;
checkcast java/lang/String
astore1 // reference to arg1
}
L3 {
getstatic java/lang/System.out:java.io.PrintStream
aload1 // reference to arg1
invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V
}
L11 {
getstatic java/lang/System.out:java.io.PrintStream
invokestatic org/sonatype/mavenbook/App.test2()Ljava/util/concurrent/CompletableFuture;
dup
invokevirtual java/util/concurrent/CompletableFuture.isDone()Z
ifne L12
astore3 // reference to arg3
astore2 // reference to arg2
aload3 // reference to arg3
invokestatic java/util/function/Function.identity()Ljava/util/function/Function;
invokevirtual java/util/concurrent/CompletableFuture.exceptionally(Ljava/util/function/Function;)Ljava/util/concurrent/CompletableFuture;
aload3 // reference to arg3
aload0 // reference to arg0
aload1 // reference to arg1
aload2 // reference to arg2
sipush 3
invokedynamic java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; : apply(Ljava/util/concurrent/CompletableFuture;Ljava/lang/String;Ljava/lang/String;Ljava/io/PrintStream;I)Ljava/util/function/Function; (Ljava/lang/Object;)Ljava/lang/Object; org/sonatype/mavenbook/App.async$test1(Ljava/util/concurrent/CompletableFuture;Ljava/lang/String;Ljava/lang/String;Ljava/io/PrintStream;ILjava/lang/Object;)Ljava/util/concurrent/CompletableFuture; (6) (Ljava/lang/Object;)Ljava/util/concurrent/CompletableFuture;
invokevirtual java/util/concurrent/CompletableFuture.thenCompose(Ljava/util/function/Function;)Ljava/util/concurrent/CompletableFuture;
areturn
}
L12 {
invokevirtual java/util/concurrent/CompletableFuture.join()Ljava/lang/Object;
checkcast java/lang/String
invokevirtual java/io/PrintStream.println(Ljava/lang/String;)V
}
L13 {
goto L11
}
L2 {
aload0 // reference to arg0
goto L8
}
L5 {
aload0 // reference to arg0
aload1 // reference to arg1
astore0 // reference to arg0
goto L10
}
L6 {
aload3 // reference to arg3
aload0 // reference to arg0
aload1 // reference to arg1
aload2 // reference to arg2
astore1 // reference to arg1
astore0 // reference to arg0
goto L12
}
L7 {
new java/lang/IllegalArgumentException
dup
invokespecial java/lang/IllegalArgumentException.<init>()V
athrow
}
}
`
which looks to be good as well.
I think this can be closed