gpt4 book ai didi

java.lang.VerifyError : Bad local variable type after bytecode instrumentation 错误

转载 作者:行者123 更新时间:2023-11-30 07:04:38 25 4
gpt4 key购买 nike

我检测了一些 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。

谁能帮帮我?

最佳答案

生成的字节码是正确的,除了你忘记更新堆栈映射表。

作为引用,这里是您生成的字节码的伪代码。

instrumentation_static_stackpointer = (instrumentation_static_stackpointer + 1) % 16
a2 = instrumentation_static_stack[instrumentation_static_stackpointer]
a2.init(-1, "isValidName_Ljava_lang_String__Z")
if (!s.matches("[_a-zA-Z][_a-zA-Z0-9]*")) goto L56
a2.clear()
instrumentation_static_stackpointer = (instrumentation_static_stackpointer - 1 + 16) % 16
return 0

L56:
if (s.toCharArray()[0] != 95) goto L87
a2.clear()
instrumentation_static_stackpointer = (instrumentation_static_stackpointer - 1 + 16) % 16
return 0

L87:
instrumentation_static_stackpointer = (instrumentation_static_stackpointer - 1 + 16) % 16
return 1

问题是,在字节码版本 51.0+ 中(大概是您正在使用的版本),必须在 StackMapTable 属性中包括有关字节码变量的类型信息。但是,您没有更新它以包含新变量 a2 的类型。只有在有跳转或跳转目标时才会查询堆栈映射表。因此,当它到达 L56 时,它查询表格以查看传入类型是什么,表格显示唯一的变量是类型为 Strings。然后它到达 a2.clear(),发现您正在使用堆栈映射表中不存在的变量,因此验证失败。

关于java.lang.VerifyError : Bad local variable type after bytecode instrumentation 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27487417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com