与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

回到顶部