Java 异常处理期间的烟尘、标识STMT和控制流

Java 异常处理期间的烟尘、标识STMT和控制流,java,exception-handling,bytecode,control-flow,soot,Java,Exception Handling,Bytecode,Control Flow,Soot,我正在尝试在coomit中编写一个try-catch块 让我们进行反编译 public class A { public static void main(String[] args) { try{ String a = args[9999]; }catch(Throwable t){ t.printStackTrace(); } System.out.println("Hel

我正在尝试在
coomit
中编写一个try-catch块

让我们进行反编译

public class A {
    public static void main(String[] args) {
        try{
            String a = args[9999];
        }catch(Throwable t){
            t.printStackTrace();
        }
        System.out.println("Hello World");
    }
}
我将在问题的末尾添加完整的反编译。重要的部分是

     0: aload_0
     1: sipush        9999
     4: aaload
     5: astore_1
     6: goto          14
     9: astore_1
    10: aload_1
    11: invokevirtual #3                  // Method java/lang/Throwable.printStackTrace:()V
    14: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
    17: ldc           #5                  // String Hello World
    19: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
    22: return

因此,这意味着,如果指令0-6中的任何一条抛出异常,控制将被重新路由到
9
,执行将继续正常进行,
astore_1
将异常对象的引用存储在局部变量中

然而,我试图在
coomit
中生成一个try-catch块,我发现一个示例实际上是这样做的:

据文献记载,

使用给定的Stmt处理程序在给定的Stmt范围上为给定的异常构造一个新异常

所以当我们看到

b.getTraps().add(Jimple.v().newTrap(thrwCls, sFirstNonId, sGotoLast, sCatch));
我们可以猜测,这实际上是在说“如果在
sFirstNonId
sGotoLast
之间的任何stmt中抛出了类型为
thrwCls
的异常,请跳转到
sCatch
的处理程序

到目前为止,这与预期相符

现在,困扰我的是

Stmt sCatch = Jimple.v().newIdentityStmt(lException1, Jimple.v().newCaughtExceptionRef());
是一个身份stmt

因为身份stmts

是定义要预加载的局部变量的语句(在方法输入时) 使用特殊值,例如参数或此值的值

例如,l0:= @this:A将本地l0定义为方法的this

此标识是必要的,因为局部变量没有编号(通常,此变量是字节码级别的局部变量插槽0中的变量。)

(第31页[编号23]中)

所以——再次以A类为例——如果我要生成(简化)

有意登记

newTrap(exception=java.lang.Throwable, beginStmt=stmt1,endStmt=stmt2,handlerStmt=stmt3)
,正如我基于反编译的
A.class
,这实际上是非法的,因为
t:=thrownException
应该是“预加载的(在方法输入时)”

但与此同时,如果要信任第86页[编号78]上的例子,这正是我们要做的

这种“预加载”的概念在它存在的时候还不存在,对我来说没有太大的意义,让我觉得我在控制流上可能是错的,尽管我不知道怎么做

有人能解释一下到底发生了什么吗

小try-catch示例的完整反编译代码:

公共A类
次要版本:0
主要版本:51
旗帜:ACC_公共、ACC_超级
固定池:
#1=Methodref#8.#28//java/lang/Object.“:()V
#2=类#29//java/lang/Throwable
#3=Methodref#2.#30//java/lang/Throwable.printStackTrace:()V
#4=Fieldref#31.#32//java/lang/System.out:Ljava/io/PrintStream;
#5=字符串#33//Hello World
#6=Methodref#34.#35//java/io/PrintStream.println:(Ljava/lang/String;)V
#7=等级#36//A
#8=类#37//java/lang/Object
#9=Utf8
#10=Utf8()V
#11=Utf8代码
#12=Utf8行号表
#13=Utf8 LocalVariableTable
#14=Utf8此
#15=Utf8 LA;
#16=Utf8主
#17=Utf8([Ljava/lang/String;)V
#18=Utf8 a
#19=Utf8 Ljava/lang/String;
#20=Utf8 t
#21=Utf8 Ljava/lang/Throwable;
#22=Utf8参数
#23=Utf8[Ljava/lang/String;
#24=Utf8堆栈映射表
#25=类#29//java/lang/Throwable
#26=Utf8源文件
#27=Utf8 A.java
#28=名称和类型#9:#10/“”:()V
#29=Utf8 java/lang/Throwable
#30=名称和类型#38:#10//printStackTrace:()V
#31=类#39//java/lang/System
#32=名称和类型#40:#41//out:Ljava/io/PrintStream;
#33=Utf8你好世界
#34=类#42//java/io/PrintStream
#35=名称和类型#43:#44//println:(Ljava/lang/String;)V
#36=Utf8 A
#37=Utf8 java/lang/Object
#38=Utf8 printStackTrace
#39=Utf8 java/lang/System
#40=Utf8输出
#41=Utf8 Ljava/io/PrintStream;
#42=Utf8 java/io/PrintStream
#43=Utf8 println
#44=Utf8(Ljava/lang/String;)V
{
公共A();
描述符:()V
旗帜:ACC_PUBLIC
代码:
堆栈=1,局部变量=1,参数大小=1
0:aload_0
1:invokespecial#1//方法java/lang/Object。“:()V
4:返回
LineNumberTable:
第1行:0
LocalVariableTable:
起始长度插槽名称签名
050本洛杉矶;
公共静态void main(java.lang.String[]);
描述符:([Ljava/lang/String;)V
标志:ACC_公共,ACC_静态
代码:
堆栈=2,局部变量=2,参数大小=1
0:aload_0
1:sipush 9999
4:aaload
5:astore_1
6:goto 14
9:astore_1
10:aload_1
11:invokevirtual#3//方法java/lang/Throwable.printStackTrace:()V
14:getstatic#4//Field java/lang/System.out:Ljava/io/PrintStream;
17:ldc#5//String Hello World
19:invokevirtual#6//方法java/io/PrintStream.println:(Ljava/lang/String;)V
22:返回
例外情况表:
从到目标类型
0 6 9类java/lang/Throwable
LineNumberTable:
第4行:0
第7行:6
Sting a;Throwable t;PrintStream out;

a = arg[9990]               //stmt1
goto stmt5                  //stmt2
t := thrownException;       //stmt3
t.printStackTrace();        //stmt4
out = System.out;           //stmt5
out.println("Hello World")  //stmt6
newTrap(exception=java.lang.Throwable, beginStmt=stmt1,endStmt=stmt2,handlerStmt=stmt3)
public class A
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #8.#28         // java/lang/Object."<init>":()V
   #2 = Class              #29            // java/lang/Throwable
   #3 = Methodref          #2.#30         // java/lang/Throwable.printStackTrace:()V
   #4 = Fieldref           #31.#32        // java/lang/System.out:Ljava/io/PrintStream;
   #5 = String             #33            // Hello World
   #6 = Methodref          #34.#35        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #7 = Class              #36            // A
   #8 = Class              #37            // java/lang/Object
   #9 = Utf8               <init>
  #10 = Utf8               ()V
  #11 = Utf8               Code
  #12 = Utf8               LineNumberTable
  #13 = Utf8               LocalVariableTable
  #14 = Utf8               this
  #15 = Utf8               LA;
  #16 = Utf8               main
  #17 = Utf8               ([Ljava/lang/String;)V
  #18 = Utf8               a
  #19 = Utf8               Ljava/lang/String;
  #20 = Utf8               t
  #21 = Utf8               Ljava/lang/Throwable;
  #22 = Utf8               args
  #23 = Utf8               [Ljava/lang/String;
  #24 = Utf8               StackMapTable
  #25 = Class              #29            // java/lang/Throwable
  #26 = Utf8               SourceFile
  #27 = Utf8               A.java
  #28 = NameAndType        #9:#10         // "<init>":()V
  #29 = Utf8               java/lang/Throwable
  #30 = NameAndType        #38:#10        // printStackTrace:()V
  #31 = Class              #39            // java/lang/System
  #32 = NameAndType        #40:#41        // out:Ljava/io/PrintStream;
  #33 = Utf8               Hello World
  #34 = Class              #42            // java/io/PrintStream
  #35 = NameAndType        #43:#44        // println:(Ljava/lang/String;)V
  #36 = Utf8               A
  #37 = Utf8               java/lang/Object
  #38 = Utf8               printStackTrace
  #39 = Utf8               java/lang/System
  #40 = Utf8               out
  #41 = Utf8               Ljava/io/PrintStream;
  #42 = Utf8               java/io/PrintStream
  #43 = Utf8               println
  #44 = Utf8               (Ljava/lang/String;)V
{
  public A();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LA;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: aload_0
         1: sipush        9999
         4: aaload
         5: astore_1
         6: goto          14
         9: astore_1
        10: aload_1
        11: invokevirtual #3                  // Method java/lang/Throwable.printStackTrace:()V
        14: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
        17: ldc           #5                  // String Hello World
        19: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        22: return
      Exception table:
         from    to  target type
             0     6     9   Class java/lang/Throwable
      LineNumberTable:
        line 4: 0
        line 7: 6
        line 5: 9
        line 6: 10
        line 8: 14
        line 9: 22
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            6       0     1     a   Ljava/lang/String;
           10       4     1     t   Ljava/lang/Throwable;
            0      23     0  args   [Ljava/lang/String;
      StackMapTable: number_of_entries = 2
        frame_type = 73 /* same_locals_1_stack_item */
          stack = [ class java/lang/Throwable ]
        frame_type = 4 /* same */
}
SourceFile: "A.java"