通过分析字节码,我如何从catch块中检测显式throw语句调用?

时间:2013-08-23 22:59:12

标签: java bytecode static-analysis

我想检测catch块中发生的throw语句。例如:

try 
{
    def();
}
catch (IOException e)
{
    throw e;
}
catch (Exception e)
{
    throw new RuntimeException(e);
}

首先,我使用Eclipse-JDT来检测这些情况,这非常简单,因为我可以遍历抽象语法树。

现在我必须使用直接处理字节码的框架(BAT - 字节码分析工具包)。

首先,如何在字节码中表示catch块?如何在其中检测throw语句?

1 个答案:

答案 0 :(得分:3)

每个方法都有一个异常表,它将一系列指令加上异常类型映射到异常处理程序(它的入口点)。这并不总是很容易转换回Java代码。但总的来说,您需要检查此表,然后分析这些入口点的可访问代码。所有代码都属于catch子句。然后,这只是确定athrow指令的问题。

使用javap或其他优秀的字节码可视化工具来更好地理解它。完成代码,编译代码并使其受javap生成:

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处有athrow。在9的入口点之后,我们有偏移量为18的athrow。就是这样!