Soot是McGill大学的Sable研究小组自1996年开始开发的Java字节码分析工具,它提供了多种字节码分析和变换功能,通过它可以进行过程内和过程间的分析优化,以及程序流图的生成,还能通过图形化的方式输出,让用户对程序有个直观的了解。尤其是做单元测试的时候,可以很方便的通过这个生成控制流图然后进行测试用例的覆盖,显著提高效率。
如果是将Soot当作简单工具来分析的人,可以直接使用Soot自带的工具soot.tools.CFGViewer分析类中的每个方法的控制流并生成DOT语言描述的控制流图,然后用graphviz中的dot命令来转换成可视化图形格式如.PNG
使用soot.tools.CFGViewer来生成Triangle.class的控制流图
进入项目bin目录下,拷贝soot.trunk.jar
1 java -cp soot-trunk.jar soot.tools.CFGViewer --soot-classpath .;"%JAVA_HOME%"\jre\lib\rt.jar TriangleClass.Triangle
为什么这里是TriangleClass.Triangle,是因为Triangle类是在TriangleClass包下的,所以类名需要加上完整包名
Triangle.java源代码如下:
1 packageTriangleClass;2
3 public classTriangle {4
5
6 public String triangle(int a, int b, intc){7
8 if(a > 0 && b > 0 && c >0){9 if(a + b >c)10 {11 if(a == b || b ==c || a ==c)12 {13 if(a == b && b ==c)14 {15 return "equilateral";16 }17 return "isosceles";18 }19 else{20 return "scalene";21 }22 }23 else{24 return "Not Triangle";25 }26 }27 else{28 return "Not Triangle";29 }30
31
32
33 }34
35 public inta;36 public intb;37 public intc;38
39 }
其中一个文件已经生成
重命名后(文件名太长了。。),使用graphviz dot转换为图片PNG格式
1 dot -Tpng -o Triangle.png Triangle.dot
再生成Test.class的控制流图:
Test.java
1 packageSoot;2
3 public classTest {4
5 private double num = 5.0;6
7 public double cal(intnum, String type){8 double temp=0;9 if(type == "sum")10 {11 for(int i = 0; i <= num; i++){12 temp =temp +i;13 }14 }15 else if(type == "average")16 {17 for(int i = 0; i <= num; i++){18 temp = temp +i;19 }20 temp = temp / (num -1);21 }else{22 System.out.println("Please enter the right type(sum or average)");23 }24 returntemp;25 }26 }
但是作为程序员,怎么能满足于简单的使用!
那么如何使用代码来在程序内部实现这个从分析代码到输出的过程呢?以下为Soot的深入理解内部代码实现生成控制流图:
Soot的输入时多源的,可以是java的字节码。Soot提供了四个中间表示法,通过将源文件转换为中间表示,基于这些中间表示传入不同的变换类来进行分析,优化或者再变换,另外还直接提供一组直接用于优化Java字节码的API。Soot的扩展机制以Pack为中心,一个Pack包括若干个变换用户可以自行设计新的变换,将其加入到soot的调度执行过程中以实现特定的功能