通过分析字节码,如何从catch块中检测到明确的throw语句调用? [英] By analyzing the bytecode, how can I detect explicit throw statement invocations from within a catch block?
问题描述
我想检测在catch块内发生的throw语句。例如:
I want to detect throw statements that occur from within a catch block. For instance:
try
{
def();
}
catch (IOException e)
{
throw e;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
首先,我使用Eclipse-JDT来检测这些情况,很简单,因为我可以遍历抽象语法树。
First, I was using Eclipse-JDT to detect these cases and it was quite simple, since I could traverse the Abstract Syntax Tree.
现在,我必须使用直接处理字节码的框架(BAT-字节码分析工具包)。
Now I have to use a framework (BAT - Bytecode Analysis Toolkit) that deals directly with the bytecode.
首先,如何在字节码中表示catch块?以及如何检测其中的throw语句?
First of all, how the catch block is represented in the bytecode? And how can I detect a throw statement within it?
推荐答案
每个方法都有一个异常表,该异常表映射了一系列指令加和异常处理程序的异常类型(它是入口点)。将其转换回Java代码并不总是那么容易。但通常,您将需要检查该表,然后从这些入口点分析可访问的代码。所有这些代码都属于 catch
子句。然后只需确定箭头
指令即可。
Each method has an Exception Table that maps a range of instructions plus and exception type to an exception handler (it's entry point). This is not always easy to translate back to Java code. But in general, you will need to examine this table and then analyse reachable code from those entry points. All of that code belongs to a catch
clause. Then it's just a matter of identifying athrow
instructions.
使用 javap
或其他不错的字节码可视化工具,可以更好地理解它。完成代码,对其进行编译,然后使其受 javap
的约束,将产生:
Use javap
or other good bytecode visualizer to play around and understand it better. Completing your code, compiling it, and subjecting it to javap
produces:
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void def() throws java.io.IOException;
Code:
0: new #2; //class java/io/IOException
3: dup
4: invokespecial #3; //Method java/io/IOException."<init>":()V
7: athrow
public static void main(java.lang.String[]) throws java.io.IOException;
Code:
0: invokestatic #4; //Method def:()V
3: goto 19
6: astore_1
7: aload_1
8: athrow
9: astore_1
10: new #6; //class java/lang/RuntimeException
13: dup
14: aload_1
15: invokespecial #7; //Method java/lang/RuntimeException."<init>":(Ljava/lang/Throwable;)V
18: athrow
19: return
Exception table:
from to target type
0 3 6 Class java/io/IOException
0 3 9 Class java/lang/Exception
}
对于方法 main
,我们有2个异常入口(目标):6和9。在6之后,我们在偏移量8处有一个 throw
。在9处的入口处,我们有一个 athrow
偏移18。就这样!
For method main
we have 2 exception entry points ("targets"): 6 and 9. Following 6, we have an athrow
at offset 8. Following the entry point at 9, we have an athrow
at offset 18. That's it!
这篇关于通过分析字节码,如何从catch块中检测到明确的throw语句调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!