通过分析字节码,如何从catch块中检测到明确的throw语句调用? [英] By analyzing the bytecode, how can I detect explicit throw statement invocations from within a catch block?

查看:101
本文介绍了通过分析字节码,如何从catch块中检测到明确的throw语句调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想检测在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆