- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我检测了一些 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 时,它查询表格以查看传入类型是什么,表格显示唯一的变量是类型为 String
的 s
。然后它到达 a2.clear()
,发现您正在使用堆栈映射表中不存在的变量,因此验证失败。
关于java.lang.VerifyError : Bad local variable type after bytecode instrumentation 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27487417/
嗯, 当我阅读并尝试每一个类似的主题但都没有成功时,我决定发布我自己的问题。我的解决方案有一个控制台应用程序和一个用于数据访问的类库。 Nhibernate 配置位于控制台应用程序的 appconfi
我正在尝试通过“Your first NHibernate based application”来了解其他类型的 ORM(我习惯于 DevExpress 的 XPO),我知道 tut 使用的版本之间存
我正在使用 Kotlin 和 Dagger 2 开发一个 Android 项目。我有一个 NetworkModule它应该提供 Retrofit 的单例实例。我在其中定义了所有这些提供程序功能。 下面
我已经用 Java 创建了一个原型(prototype) VM(因为它是我最熟悉的语言),并且我正在尝试以字节码格式存储指令。我想知道如何在字节码中存储值,因为字节只能是 0 到 255。 举个例子:
我一直在尝试使用 ASM 框架在我感兴趣的位置注入(inject)字节码,到目前为止我已经成功了。目前我正在尝试注入(inject)代码,该代码基本上创建了一个类的新实例/对象,在阅读了一些内容之后,
假设没有为程序生成字节码,例如在 Ruby、Perl 或 PHP 中,在这种情况下,每次执行到第 1 行时是否重新解释下面的第 1 行? while ($indexArrayMoviesData <
我需要使用卡片外的字节码验证器来验证Java Card程序(盖帽文件)。 我已经手动修改了cap文件中的信息,并且我想验证新的cap文件是否类型正确。 我尝试使用com.sun.javacard.sc
我在 Startup 中设置了以下代码 IDictionary properties = new Dictionary(); properties.Add("connection.driver_cla
我在哪里可以获得NHibernate.ByteCode.CaSTLe.ProxyFactoryFactory源代码?它在 NHibernate 存储库中,但大约一个月前被删除了。它现在在哪里? 谢谢!
没有dup指令,一个让我复制堆栈顶部的指令。我可以使用哪个指令序列来复制这种行为? 最佳答案 Wasm 没有堆栈杂耍原语,因为它有局部变量。要复制操作数堆栈的顶部,您需要定义一个正确类型的局部变量。然
据我了解,GHC(Glorious Glasgow Haskell 编译器)将 Haskell 编译为“Core”,然后将该 Core 编译为机器代码。将 Haskell 程序作为 GHC Core
有一些框架可用于动态字节码生成、操作和编织(BCEL、CGLIB、javassist、ASM、MPS)。我想了解它们,但由于我没有太多时间了解所有这些的所有细节,我想看一种比较图表,说明一个与其他的优
我修改了程序集的字节码以消除错误,现在当我尝试使用它时,我得到了一个 InvalidProgramException。我所做的就是用 NOPS 替换这段代码: catch (Exception exc
我修改了程序集的字节码以消除错误,现在当我尝试使用它时,我得到了一个 InvalidProgramException。我所做的就是用 NOPS 替换这段代码: catch (Exception exc
Python 是解释型而非编译型,这意味着每一行源代码都被逐行编译为 BYTECODE。 (我刚才使用的术语“编译”是正确的吗?) 谁执行从源代码到 BYTECODE 的转换?(这是解释器程序吗?).
我正在研究 a fork来自 Jetbrains 的 FernFlower,我一直在对其进行小的改进。 关于 FernFlower 真正让我恼火的一件事是,它根据局部变量在 bpush/spush 等
这个问题几乎说明了一切,我一直在四处寻找答案,甚至通过 VM 规范,但我没有明确说明。 最佳答案 没有。 不过,还有其他一些具有跟踪 JIT 的 JVM:HotPath和 Maxine ,例如。 关于
我目前正在编写一个针对翻译中的 Java 字节码的玩具编译器。 我想知道在编写 .class 文件之前,是否存在可以在发出的字节码中进行的各种简单窥视孔优化的某种目录,也许是摘要。我实际上知道一些库具
我按照 http://asm.ow2.org/current/asm-transformations.pdf 中“3.2.6 内联方法”中的示例代码,将 MethodNode 内联到调用站点。 我的问
我在 *nix 上看到的一切都是对硬件的一组抽象,但我很好奇硬件是如何工作的。 我已经在汇编中进行了编程,但这仍然只是一组抽象。 处理器如何理解汇编操作码(作为字节码)? 设备驱动程序如何工作(在较低
我是一名优秀的程序员,十分优秀!