3

我的一个类上有 JVM (1.6.0b33) throw java.lang.VerifyError (Incompatible object argument for function call)。使用 javassist(使用 CtMethod.make())对该类进行检测(仅此一种方法)

有没有办法让我找到哪个方法调用触发了错误?我浏览了 javap -c -s -l 的输出,但我没有看到任何调用指令有任何问题。

例如,如果有人知道如何要求 JVM 提供有关检测到此错误的位置的更多详细信息(代码地址会很好)就足够了,所以我知道应该关注哪里。如果有人想以这种方式破解它,我可以发布 javap 的输出......

4

1 回答 1

6

在检查 JVM 源代码后想通了。

The error (Incompatible object argument for function call) means that the object on which the invocation is performed doesn't match the expected (by method signature) type (I assumed it had something to do with object arguments, but you get a slightly different error in that case).

Apparently, javassist doesn't insert proper instructions when you assign an object to an object of another class (alternatively it can fail the statement).

Javassist will take the following code as valid:

Object x ...;
String s = x; // javac requires cast here, javassist doesn't
s.isEmpty();

normally compiles into:

1 aload_1 // push x on stack
2 checkcast java/lang/String // check we can fit x into s
3 astore 2 // s = x;
4 aload 2 // 'this' for isEmpty()
5 invokevirtual String.isEmpty() // stack top used as 'this'

javassist (at least the version that I have) just doesn't add checkcast instruction, and the VM has no guarantee that at the time invokevirtual is called the stack top contains String, which is required because the invokvirtual is invoking a method from String class.

Remedy would be:

  • use explicit cast in assignments
  • fix javassist
  • use local variables of explicit type
于 2013-03-30T08:45:50.707 回答