【发布时间】:2014-12-15 15:27:24
【问题描述】:
我检测了一些 Java 字节码。我尝试做的是:
InstrumentStackElem[] stack;
int stackpointer;
void foo(){
stackpointer = (stackpointer + 1) % stack.length;
InstrumentStackElem localref = stack[stackpointer];
localref.init();
//before each return
localref.clear();
stackpointer = (stackpointer -1 +stack.length) % stack.length;
因此,在每个方法的开头,我都会递增堆栈指针并获取对数组元素的本地引用。在每次返回之前,我在元素上调用一个 clear 方法并再次减少计数器。
当我尝试访问调用 localref.clear() 的字段时,我总是收到 java.lang.VerifyError。
示例方法:
public static boolean isValidName(final String s) {
if (!s.matches("[_a-zA-Z][_a-zA-Z0-9]*")) {
return false;
}
if (s.toCharArray()[0] == '_') { // this check should not be -> this is
// a bug
return false;
}
return true;
}
相应的检测字节码
public static boolean isValidName(java.lang.String);
Code:
0: getstatic #38 // Field instrumentation_static_stackpointer:I
3: iconst_1
4: iadd
5: bipush 16
7: irem
8: putstatic #38 // Field instrumentation_static_stackpointer:I
11: getstatic #40 // Field instrumentation_static_stack:[Lme/instrumentor/InstrumentStackElem;
14: getstatic #38 // Field instrumentation_static_stackpointer:I
17: aaload
18: astore_2
19: aload_2
20: bipush -1
22: ldc #113 // String isValidName_Ljava_lang_String__Z
24: invokevirtual #48 // Method me/instrumentor/InstrumentStackElem.init:(ILjava/lang/String;)V
27: aload_0
28: ldc #115 // String [_a-zA-Z][_a-zA-Z0-9]*
30: invokevirtual #118 // Method java/lang/String.matches:(Ljava/lang/String;)Z
33: ifne 56
36: iconst_0
37: aload_2
38: invokevirtual #110 // Method me/instrumentor/InstrumentStackElem.clear:()V
41: getstatic #38 // Field instrumentation_static_stackpointer:I
44: iconst_1
45: isub
46: bipush 16
48: iadd
49: bipush 16
51: irem
52: putstatic #38 // Field instrumentation_static_stackpointer:I
55: ireturn
56: aload_0
57: invokevirtual #122 // Method java/lang/String.toCharArray:()[C
60: iconst_0
61: caload
62: bipush 95
64: if_icmpne 87
67: iconst_0
68: aload_2
69: invokevirtual #110 // Method me/instrumentor/InstrumentStackElem.clear:()V
72: getstatic #38 // Field instrumentation_static_stackpointer:I
75: iconst_1
76: isub
77: bipush 16
79: iadd
80: bipush 16
82: irem
83: putstatic #38 // Field instrumentation_static_stackpointer:I
86: ireturn
87: iconst_1
88: aload_2
89: invokevirtual #110 // Method me/instrumentor/InstrumentStackElem.clear:()V
92: getstatic #38 // Field instrumentation_static_stackpointer:I
95: iconst_1
96: isub
97: bipush 16
99: iadd
100: bipush 16
102: irem
103: putstatic #38 // Field instrumentation_static_stackpointer:I
106: ireturn
这是引发的确切错误:
Unexpected error: Lexer: java.lang.VerifyError: Bad local variable type
Exception Details:
Location:
lexer/Lexer.isValidName(Ljava/lang/String;)Z @68: aload_2
Reason:
Type top (current frame, locals[2]) is not assignable to reference type
Current Frame:
bci: @68
flags: { }
locals: { 'java/lang/String' }
stack: { integer }
Bytecode:
0000000: b200 2604 6010 1070 b300 26b2 0028 b200
0000010: 2632 4d2c 10ff 1271 b600 302a 1273 b600
0000020: 769a 0017 032c b600 6eb2 0026 0464 1010
0000030: 6010 1070 b300 26ac 2ab6 007a 0334 105f
0000040: a000 1703 2cb6 006e b200 2604 6410 1060
0000050: 1010 70b3 0026 ac04 2cb6 006e b200 2604
0000060: 6410 1060 1010 70b3 0026 ac
Stackmap Table:
same_frame(@56)
same_frame(@87)
我使用 asm 库来检测方法并使用 this.method.visitLocalVariable("localstackref", "[Lme/instrumentor/InstrumentStackElem;",null, bl, el,this.stackelementindex); 添加局部变量。 stackelementindex 在这种情况下是 2。
有人可以帮帮我吗?
【问题讨论】:
标签: java bytecode java-bytecode-asm