[Soot-list] Problem building callgraph

Eric Bodden bodden at st.informatik.tu-darmstadt.de
Sat Sep 19 04:54:12 EDT 2009


Hi Marcos.

It's as I expected. You are using Soot in a wring way. You call
soot.Main.main and then *afterwards* try to access method bodies. That
won't work because after Soot"s main method has finished a lot of the
information that the Scene contains is "free'd", i.e. is discarded,
and hence you cannot access this information any more.

The right way to do this would be to implement your analysis within a
SceneTransformer in the "wjtp" pack. Please see the PLDI tutorial
(http://www.sable.mcgill.ca/soot/tutorial/pldi03/tutorial.pdf, around
slide 100) and this tutorial for details:
http://www.bodden.de/2008/09/22/soot-intra/

In case yo use Soot's eclipse plug-in you can also just select
New->Example in eclipse to create a stub for such a transformer.

Eric

2009/9/18 Marcos Chicote <totochicote at gmail.com>:
> Eric,
>
> Here's the code I'm using. PurityClass is the example and Analysis is where
> I create the CFG.
> When I try to retrieve the body, I get a NPE in SootMethod class in line 82
> beacause ms, the method source seems to be null.
>
> Thanks for your help and time!
>
> **************************************************** PurityClass
> *****************************************************
>
> package ar.uba.dc.salcian;
>
> /**
>  * This example is from the article "A Combined Pointer and Purity Analysis
> for
>  * Java Programs" by Alexandru Salcianu and Martin Rinard. It is supposed to
>  * demonstrate the purity analysis (-annot-purity)
>  *
>  * by Antoine Mine, 2005/02/08
>  */
>
> class List {
>
>     Cell head = null;
>
>     void add(Object e) {
>         head = new Cell(e, head);
>     }
>
>     ListItr iterator() {
>         return new ListItr(head);
>     }
> }
>
> class Cell {
>
>     Object data;
>     Cell next;
>
>     public Cell(Object d, Cell n) {
>         data = d;
>         next = n;
>     }
> }
>
> interface Iterator {
>     boolean hasNext();
>
>     Object next();
> }
>
> class ListItr /*implements Iterator*/ {
>
>     Cell cell;
>
>     public ListItr(Cell head) {
>         cell = head;
>     }
>
>     public boolean hasNext() {
>         boolean hasNext = (cell != null);
>         return hasNext;
>     }
>
>     public Object next() {
>         Object result = cell.data;
>         cell = cell.next;
>         return result;
>     }
> }
>
> class Point {
>
>     float x, y;
>
>     public Point(float x, float y) {
>         this.x = x;
>         this.y = y;
>     }
>
>     public void flip() {
>         float t = x;
>         x = y;
>         y = t;
>     }
>
>     void print() {
>         int a = 3;
>         System.out.print("(" + x + "," + y + ")");
>     }
> }
>
> public class PurityTest {
>
>     static float sumX(List list) {
>         float s = 0;
>         ListItr it = list.iterator();
>         while (it.hasNext()) {
>             Point p = (Point) it.next();
>             s += p.x;
>         }
>         return s;
>     }
>
>     static void flipAll(List list) {
>         ListItr it = list.iterator();
>         while (it.hasNext()) {
>             Point p = (Point) it.next();
>             p.flip();
>         }
>     }
>
>     static void print(List list) {
>         ListItr it = list.iterator();
>         System.out.print("[");
>         while (it.hasNext()) {
>             Point p = (Point) it.next();
>             p.print();
>             if (it.hasNext())
>                 System.out.print(";");
>         }
>         System.out.println("]");
>     }
>
>     public static void main(String args[]) {
>         List list = new List();
>         list.add(new Point(1, 2));
>         list.add(new Point(2, 3));
>         list.add(new Point(3, 4));
>         print(list);
>         System.out.println("sum=" + sumX(list));
>         sumX(list);
>         print(list);
>         flipAll(list);
>         print(list);
>     }
> }
>
> **************************************************** End PurityClass
> *****************************************************
>
> **************************************************** AnalysisClass
> *******************************************************
>
> public class Analysis {
>     public static void main(String[] args) {
>         CallGraph cg = generateCallGraph("ar.uba.dc.salcian.PurityTest");
>     /*    String[] cgArgs = {"ar.uba.dc.salcian.PurityTest",
> "ar.uba.dc.salcian.ListItr"};
>         CGMain.main(cgArgs);
>         SootClass mainClass =
> Scene.v().getSootClass("ar.uba.dc.salcian.PurityTest");
>         Scene.v().setMainClass(mainClass);
>         Scene.v().loadNecessaryClasses();
>         CallGraph cg = Scene.v().getCallGraph();*/
>
>
>
>         SootClass sootClass2 =
> Scene.v().getSootClass("ar.uba.dc.salcian.ListItr");
>         SootMethod sootMethod2 = sootClass2.getMethodByName("hasNext");
>         sootMethod2.retrieveActiveBody();
> }
>
>     public static CallGraph generateCallGraph(String strClass)
>     {
>         CallGraph cg=null;
>         String[] opts = {"-f", "n", "-w","-app",
>                          "--full-resolver",
>                          "-allow-phantom-refs",
>                          "-p", "cg", "enabled:true",
>                          //"-p", "cg.spark","enabled:true",
>                          //"-p", "cg.spark","on-fly-cg:true",
>                          "-p","jb","use-original-names:true",
>                          "-p","jb.dae","enabled:false",
>                           "-p", "jj", "use-original-names:true",
>                           "-p","jj.dae", "enabled:false",
>                           "-p","jj.ule", "enabled:false",
>                          "-p", "cg", "safe-newinstance:true",
>                          "-p", "cg", "safe-forname:true",
>                          "-p", "cg", "all-reachable:on",
>                          // "-p","cg","context:insens",
>                          "-p", "tag.ln", "enabled:true",
>                          // "-p", "jap.cgtagger", "enabled:true",
>                          //"-p", "wjop.smb", "enabled:true",
>                          // "-p", "cg.spark", "enabled:true",
>                          // "-p", "cg.spark", "add-tags:true",
>                          // "-p", "cg.spark", "dump-html:true",
>                          // "-p", "cg.spark", "simplify-offline:true",
>                           strClass};
>
>         //set the options to the static main class
>         System.out.println("Set options to the static main class");
>         soot.Main.main(opts);
>
>         SootClass sootClass = Scene.v().loadClassAndSupport(strClass);
>         sootClass.setApplicationClass();
>         Scene.v().setMainClass(sootClass);
>         Scene.v().loadNecessaryClasses();
>
>         cg = Scene.v().getCallGraph();
>         return cg;
>
>     }
>
> **************************************************** End AnalysisClass
> ****************************************************
>
>
> On Thu, Sep 17, 2009 at 4:10 AM, Eric Bodden
> <bodden at st.informatik.tu-darmstadt.de> wrote:
>>
>> Hi Marcos.
>>
>> It's hard to say because it's likely that your mistake is not in the
>> code snippet you sent us. Can you post your whole code? Or even
>> better, first cut it down into a minimal failing example.
>>
>> Eric
>>
>> 2009/9/16 Marcos Chicote <totochicote at gmail.com>:
>> > Hi
>> > I'm new in Soot, so this might be a really stupid problem. I have read
>> > the
>> > documentation but couldn't make this work.
>> > I'm trying to build a callgraph. I'm using Guillaume Salagnac's launcher
>> > with this options:
>> >
>> >         addDefaultOpt("-w");
>> >         addDefaultOpt("-f","J");
>> >         addDefaultOpt("-app");
>> >
>> >         //addDefaultOpt("-i","java"); Original
>> >         addDefaultOpt("-x","java"); // Marcos
>> >         addDefaultOpt("-x","sun"); // Marcos
>> >         //addDefaultOpt("-include-all");
>> >
>> >         addDefaultOpt("-allow-phantom-refs");
>> >
>> >         addDefaultOpt("-keep-line-number");
>> >         addDefaultOpt("-keep-bytecode-offset");
>> >         addDefaultOpt("-src-prec","class");
>> >
>> >         addDefaultOpt("-p","cg","enabled:true"); //Marcos
>> >         //addDefaultOpt("-p","cg.spark","enabled:true");Original
>> >         addDefaultOpt("-p","cg","all-reachable:true");
>> >         //addDefaultOpt("-p","cg","verbose:true");
>> >         addDefaultOpt("-p","jb","use-original-names:true");
>> >
>> > After creating the callgraph, when I try to execute this:
>> >
>> >         SootClass sootClass2 =
>> > Scene.v().getSootClass("ar.uba.dc.salcian.ListItr");
>> >         SootMethod sootMethod2 = sootClass2.getMethodByName("hasNext");
>> >         sootMethod2.retrieveActiveBody();
>> >         sootMethod2.getActiveBody();
>> >
>> > I get a NPE in getBodyFromMethodSource in SootMethod class. Method
>> > source
>> > seems to be null.
>> >
>> > This is the definition of the method whos body I'm trying to access:
>> >
>> >     public boolean hasNext() {
>> >         boolean hasNext = (cell != null);
>> >         return hasNext;
>> >     }
>> >
>> > Can someone help me with this? If more information is needed please ask
>> > me!
>> >
>> > Thanks a lot!
>> > Marcos
>> >
>> > _______________________________________________
>> > Soot-list mailing list
>> > Soot-list at sable.mcgill.ca
>> > http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
>> >
>> >
>>
>>
>>
>> --
>> Eric Bodden
>> Software Technology Group, Technische Universität Darmstadt, Germany
>> Tel: +49 6151 16-5478    Fax: +49 6151 16-5410
>> Mailing Address: S2|02 A209, Hochschulstraße 10, 64289 Darmstadt
>
>



-- 
Eric Bodden
Software Technology Group, Technische Universität Darmstadt, Germany
Tel: +49 6151 16-5478    Fax: +49 6151 16-5410
Mailing Address: S2|02 A209, Hochschulstraße 10, 64289 Darmstadt


More information about the Soot-list mailing list