[Soot-list] throw analysis

John Jorgensen jorgnsn at lcd.uregina.ca
Tue Jun 21 00:33:35 EDT 2005


>>>>> "rugang" == Ru-Gang Xu <rugang at gmail.com> writes:

    rugang> I'm wondering if there are more precise ThrowAnalysis
    rugang> classes (versus the included Pedantic and
    rugang> UnitThrowAnalysis) out there? 

Not that I am aware of.  Contributions are eagerly solicited.

    rugang> It seems to me both PedanticThrowAnalysis and
    rugang> UnitThrowAnalysis when used to make an
    rugang> ExceptionalIUnitGraph will include edges that just
    rugang> allow exceptions to be thrown anywhere, even from
    rugang> statements that cannot throw exceptions.  

Could you describe the observations that make
PedanticThrowAnalysis and UnitThrowAnalysis look alike?  I'm
curious about how you are determining which exceptional edges
exist; the two ThrowAnalysis classes definitely differ, so
something about what you are examining at is making them look
alike.

I'll describe one means--admittedly somewhate awkward--for
comparing the CFGs produced by different throw analyses.

Soot includes a batch tool for visualizing the CFGs (by now there
may be interactive CFG viewers in the Eclipse plug-in as well,
but I'm out of touch with that).  You need the graphviz package
(http://www.graphviz.org) to turn visualization files into
visible output.

I'm attaching a sample program, ExceptionalGraphDemo.  Try
compiling this, then running

    java -classpath $SOOT_CLASSES:$JASMIN_CLASSES:$POLYGLOT_CLASSES \
      soot.tools.CFGViewer -d trimmed-cfgs \
      --graph=ExceptionalUnitGraph --ir=jimple \
      --show-exception-dests --trim-cfgs ExceptionalGraphDemo

and 

    java -classpath $SOOT_CLASSES:$JASMIN_CLASSES:$POLYGLOT_CLASSES \
      soot.tools.CFGViewer -d untrimmed-cfgs \
      --graph=ExceptionalUnitGraph --ir=jimple
      --show-exception-dests  ExceptionalGraphDemo

where you'll have to provide suitable substitutions for the
variables in the class path.

CFGViewer produces a *.dot file for each method, containing the
specified CFG for the method (try "CFGViewer --help").  Be
warned that the resulting files have spaces and parentheses in
their names, so they can be awkward to deal with from the shell.

As explained in 

  http://www.sable.mcgill.ca/soot/tutorial/usage/

--trim-cfg is shorthand for the options 

  --throw-analysis unit --omit-excepting-unit-edges -p jb.tt enabled:true

See the usage guide and the javadoc for ExceptionalUnitGraph for
more details, but essentially, "--trim-cfg" tells Soot to use
UnitThrowAnalysis instead of PedanticThrowAnalysis for creating
most ExceptionalUnitGraphs, and make some ancillary adjustments.

Comparing the dot files in the trimmed-cfgs and
untrimmed-cfgs directories should confirm that the different
ThrowAnalysis classes produce different results.  This will be
most clear for method0(), where the UnitThrowAnalysis will
produce no exceptional edges at all.  

There are lots of ways you can look at the *.dot files.
I usually run this file to get a PDF (on Linux):

  dot -Gmargin=0.013 -Gsize="7.5,10" -Tps2 "$dotfile" | ps2pdf14 - > $pdffile

The dotty command doesn't required this preprocessing step, but I
find the PDF viewers easier to deal with. For me, 
regular control flow edges are black, exceptional control flow
edges are red, and edges indicating where exceptions are caught
(which are not exactly control flow edges) are grey---but if I
recall correctly, all the colors are configurable. 

    rugang> I'm wondering whether anyone has done better or am I just
    rugang> no using throw analysis correctly (i.e. there some
    rugang> others options to tweak than just passing the
    rugang> UnitThrowAnalysis to the ExceptionalUnitGraph
    rugang> constructer).? 

Trying to think of ways you could go wrong, I can think of two
possibilities:

    -  you might be creating an ExceptionalUnitGraph at one point
       for your own analysis, unaware that Soot creates lots of
       ExceptionalUnitGraphs on its own in the course of
       processing the class before it ever gets to your analysis
       (if you have lots of disk space, you can use Soot's
       "--dump-cfg ALL" switch to have it produce a dot file for
       every CFG it creates; this is actually a more meaningful
       indication of what is going on within Soot, since the
       files produced by CFGViewer are created from the class
       _after_ all of Soot's manipulations, and may not be a good
       indicator of the CFG actually seen by intermediate
       analyses).

     - perhaps you have too optimistic expectations of
       "statements that cannot throw exceptions", and so are
       surprised to see edges from what seem like innocuous
       instructions to some handler that catches Throwable. In my
       experience, a large proportion of handlers observed in the
       wild catch Throwable, rather than a more specific type,
       perhaps because they are generated from "finally"
       statements or synchronized blocks, and these handlers are
       going to have edges from every instruction they cover,
       since absolutely all instructions have the potential to
       throw an asynchronous Error. See

         http://www.sable.mcgill.ca/publications/techreports/#report2003-3

       for mind-numbing detail on this question.

-------------- next part --------------
/**
 * An example class to demonstrate different CFGs produced by
 * ExceptionalUnitGraph and PedanticUnitGraph.
 */

import java.awt.color.CMMException; // A RuntimeException that no instruction
                                    // throws implicitly.

public class ExceptionalGraphDemo {
    int field = 0;

  public void method0(int a[], int i, int b) {
    try {
      int temp = a[i];	//1 dest:Esc uCFG:2 eCFG:
      temp = temp/b;	//2 dest:Esc uCFG:3 eCFG:
      field = temp;	//3 dest:Esc uCFG:t eCFG:
    } catch (CMMException e) {
      field = -1;	//4 dest:Esc uCFG:t eCFG:
    }
  }

  public void method1(int a[], int i, int b) {
    try {
      int temp = a[i];	//1 dest:4,5 uCFG:2 eCFG:6
      temp = temp/b;	//2 dest:6   uCFG:3 eCFG:
      field = temp;	//3 dest:Esc uCFG:t eCFG:
    } catch (NullPointerException e) {
      field = -1;	//4 dest:Esc uCFG:t eCFG:
    } catch (ArrayIndexOutOfBoundsException e) {
      field = -2;	//5 dest:Esc uCFG:t eCFG:
    } catch (ArithmeticException e) {
      field = -3;	//6 dest:Esc uCFG:t eCFG:
    }
  }

  public void method2(int a[], int i, int b, int c) {
    int result = 0;		//1 dest:Esc   uCFG:2 eCFG:11
    try {
      result = field;		//2 dest:11    uCFG:3 eCFG:11
      int temp = a[i];		//3 dest:11    uCFG:4 eCFG:10,11
      temp = temp/b;		//4 dest:10,11 uCFG:5 eCFG:9,11
      result = result + temp;	//5 dest:9,11  uCFG:6 eCFG:11
      try {
	result = result + c;	//6 dest:11    uCFG:7 eCFG:8,11
	result = result/c;	//7 dest:8,11  uCFG:9 eCFG:10,11
      } catch (CMMException e) {
	result = -1;
      } catch (RuntimeException re) {
	result = -2;		//8 dest:11    uCFG:9 eCFG:10,11
      }
      result = 2/result;	//9 dest:10,11 uCFG:11 eCFG:11
    } catch (ArithmeticException ae) {
      result = -3;		//10 dest:11   uCFG:11 eCFG:11
    } finally {
      field = result;		//11 dest:11 uCFG:t  eCFG:11
    }
  }

}


More information about the Soot-list mailing list