与ASM字节码检测功能不兼容的参数
我遇到了一些麻烦,运行一个简单的主程序与番石榴库。与ASM字节码检测功能不兼容的参数
我已经仪表类使用我的代码从这里获取方法的参数:Java method parameters values in ASM
的问题是,虽然该代码适用于小型项目(河内又名塔),与番石榴我有错误,例外。
特别地,测试Joiner.join方法时,我有这样的错误:
Exception in thread "Jalen Agent" java.lang.VerifyError: (class: com/google/common/base/Joiner, method: withKeyValueSeparator signature: (Ljava/lang/String;)Lcom/google/common/base/Joiner$MapJoiner;) Incompatible argument to function at Main.joinBench(Main.java:42)
at Main.main(Main.java:20)
并采用-noverify运行示例的情况下,我有一个例外:
Exception in thread "Jalen Agent" java.lang.ArrayIndexOutOfBoundsException: 1 at com.google.common.base.Joiner.<init>(Joiner.java)
at com.google.common.base.Joiner.on(Joiner.java:71)
at Main.joinBench(Main.java:42)
at Main.main(Main.java:20)
字节码的方法是一致的:
public static com.google.common.base.Joiner on(java.lang.String); Code:
0: bipush 1
2: anewarray #4 // class java/lang/Object
5: astore_1
6: aload_1
7: bipush 0
9: aload_0
10: aastore
11: ldc #20 // int 369
13: ldc #21 // String com/google/common/base/Joiner
15: ldc #22 // String on
17: aload_1
18: invokestatic #28 // Method jalen/MethodStats.onMethodEntry:(ILjava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
21: new #2 // class com/google/common/base/Joiner
24: dup
25: aload_0
26: invokespecial #32 // Method "<init>":(Ljava/lang/String;)V
29: ldc #20 // int 369
31: invokestatic #36 // Method jalen/MethodStats.onMethodExit:(I)V
34: areturn
我知道错误可能与图书馆有关ies版本,但主要的java程序是针对检测过的库编译的,并使用库的同一个罐子运行。
为什么会发生这种情况的任何想法?以及如何解决?
谢谢:)
编辑
这里有方法withKeyValueSeparator的字节码前和后插
原始字节码:
public com.google.common.base.Joiner$MapJoiner withKeyValueSeparator(java.lang.String); Code:
0: new #33 // class com/google/common/base/Joiner$MapJoiner
3: dup
4: aload_0
5: aload_1
6: aconst_null
7: invokespecial #34 // Method com/google/common/base/Joiner$MapJoiner."<init>":(Lcom/google/common/base/Joiner;Ljava/lang/String;Lcom/google/common/base/Joiner$1;)V
10: areturn
仪器化的字节码:
public com.google.common.base.Joiner$MapJoiner withKeyValueSeparator(java.lang.String); Code:
0: bipush 1
2: anewarray #4 // class java/lang/Object
5: astore_1
6: aload_1
7: bipush 1
9: aload_1
10: aastore
11: ldc #199 // int 390
13: ldc #21 // String com/google/common/base/Joiner
15: ldc #200 // String withKeyValueSeparator
17: aload_1
18: invokestatic #28 // Method jalen/MethodStats.onMethodEntry:(ILjava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
21: new #8 // class com/google/common/base/Joiner$MapJoiner
24: dup
25: aload_0
26: aload_1
27: aconst_null
28: invokespecial #203 // Method com/google/common/base/Joiner$MapJoiner."<init>":(Lcom/google/common/base/Joiner;Ljava/lang/String;Lcom/google/common/base/Joiner$1;)V
31: ldc #199 // int 390
33: invokestatic #36 // Method jalen/MethodStats.onMethodExit:(I)V
36: areturn
下面是木匠类的完整的字节码:
原文:http://pastebin.com/VsccVX18
仪表:http://pastebin.com/xtke1a8y
回答:
首先,我不明白为什么这应该是有关库的版本。看起来字节码没有正确检测,导致验证失败,如果使用-noverify,则会出现异常。
关于验证错误,它表明Joiner.withKeyValueSeparator()中有错误。此方法的代码尝试调用具有不兼容方法参数的另一个方法。你可以给withKeyValueSeparator()方法的检测字节码吗? (以及非仪器化的)
用-noverify看到的错误发生在Joiner的构造函数中,Joiner.on()方法似乎没有错。再次,你可以发布Joiner的字节码。方法? (仪器化和非仪器化)
回答:
withKeyValueSeparator
的原始代码将其一系列参数传递给MapJoiner
构造函数。您正在添加将数组存储在本地变量表的第二个插槽中的检测代码(使用astore_1
)。这将覆盖第一个参数withKeyValueSeparator
,这是一个String
。 (局部变量表的第一时隙是MapJoiner
实例本身,又名this
。),所以当原来的功能的代码试图传递对象的局部变量表的构造的第二时隙,存在“不兼容的变量”错误。
为了解决这个问题,你应该在分配您的阵列中的局部变量表的新插槽; this answer概述了如何。
以上是 与ASM字节码检测功能不兼容的参数 的全部内容, 来源链接: utcz.com/qa/265235.html