[Soot-list] Cannot reach transitive methods in Call Graph

Ondrej Lhotak olhotak at uwaterloo.ca
Wed Jul 27 09:57:42 EDT 2011


ReachableMethods does not do what you think it does.

It is a queue to which methods that are reachable in any way through the
call graph are added as calls to them are encountered, provided that
they have not been added before. If the call graph is already completely
constructed, no additional methods will ever be added to a
ReachableMethods object.

I don't think there's a method that computes methods transitively
reachable from a call site or method for you, but it should be
quite easy to build such a search using the methods in
soot.jimple.toolkits.callgraph.CallGraph.

On Wed, Jul 27, 2011 at 02:10:59PM +0100, John Dee wrote:
> Yep the edges are there.
> 
> I updated the code in my class that is to be analysed to:
> 
> public class CallGraphs
> {
> public static void main(String[] args) {
> doStuff();
> }
> @Criteria(profile = "med")
> public static void doStuff() {
> StringBuilder b = new StringBuilder("Blah");
> b.append(" Blah");
> new A().foo();
> }
> }
> 
> class A
> {
> int x;
> public A() {
> x = 19;
> }
> 
> public void foo() {
> int a = bar();
> }
> public int bar() {
> x++;
> return x;
> }
> }
> 
> And the output is:
> 
> Soot started on Wed Jul 27 14:05:51 BST 2011
> [Call Graph] For information on where the call graph may be incomplete, use the
> verbose option to the cg phase.
> [Call Graph] For information on where the call graph may be incomplete, use the
> verbose option to the cg phase.
> <testers.CallGraphs: void doStuff()> may call <java.lang.AbstractStringBuilder:
> void <clinit>()>
> <testers.CallGraphs: void doStuff()> may call <testers.A: void foo()>
> <testers.CallGraphs: void doStuff()> may call <testers.A: void <init>()>
> <testers.CallGraphs: void doStuff()> may call <java.lang.StringBuilder:
> java.lang.StringBuilder append(java.lang.String)>
> <testers.CallGraphs: void doStuff()> may call <java.lang.StringBuilder: void
> <init>(java.lang.String)>
> <testers.CallGraphs: void doStuff()> may call <java.lang.Object: void <clinit>
> ()>
> <testers.CallGraphs: void doStuff()> may call <java.lang.Object: void <clinit>
> ()>
> Num transitive methods 0
> Transforming testers.CallGraphs... 
> Transforming testers.A... 
> Writing to sootOutput\testers\CallGraphs.class
> Writing to sootOutput\testers\A.class
> Soot finished on Wed Jul 27 14:06:41 BST 2011
> Soot has run for 0 min. 49 sec.
> 
> As you can see, the following piece of code is working ok:
> 
> Iterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src));
> while (targets.hasNext()) {
>     SootMethod tgt = (SootMethod)targets.next();
>     System.out.println(src + " may call " + tgt);
> }
> 
> However, the following code isn't generating any results
> 
>       ReachableMethods reachableMethods = new ReachableMethods(cg, targets);
>       QueueReader<MethodOrMethodContext> transitiveMethods = 
>       reachableMethods.listener();
>       reachableMethods.update();
>       System.out.println("Num transitive methods " + reachableMethods.size());
>       while (transitiveMethods.hasNext()) {
>       System.out.println(src + " may reach " + ((SootMethod)
> transitiveMethods.next()).getName());
>       }
> 
> Is there an option that I may be missing? Such as all-reachable?
> 
> Thanks,
> JD
> 
> > From: bodden at st.informatik.tu-darmstadt.de
> > Date: Wed, 27 Jul 2011 14:58:45 +0200
> > Subject: Re: [Soot-list] Cannot reach transitive methods in Call Graph
> > To: jdsoot at hotmail.com
> > CC: soot-list at sable.mcgill.ca
> >
> > This looks ok to me.
> >
> > Are the edges present in the graph?
> >
> > Did you try adding code to bar()? Maybe it gets optimized away...
> >
> > Eric
> >
> > On 27 July 2011 14:50, John Dee <jdsoot at hotmail.com> wrote:
> > > Hi there.
> > > I the following 2 classes, which will be used for generating a call graph.
> > > public class CallGraphs
> > > {
> > > public static void main(String[] args) {
> > > doStuff();
> > > }
> > > @Criteria(profile = "med")
> > > public static void doStuff() {
> > > StringBuilder b = new StringBuilder("Blah");
> > > b.append(" Blah");
> > > new A().foo();
> > > }
> > > }
> > > class A
> > > {
> > > public void foo() {
> > > bar();
> > > }
> > > public void bar() {
> > > }
> > > }
> > > My call graph code looks like
> > > public class CallGraphExample
> > > {
> > > public static void main(String[] args) {
> > > // create a list from args
> > >   List<String> argsList = new ArrayList<String>(Arrays.asList(args));
> > >
> > >   // add on the following arguments
> > >   argsList.addAll(Arrays.asList(new String[]{
> > >   "-w",
> > >   "-main-class",
> > >   "testers.CallGraphs",
> > >   "testers.CallGraphs",//argument classes
> > >   "testers.A"
> > >   }));
> > >
> > >   // PackManager manages the packs containing the various phases and their
> > > options
> > >   PackManager.v().getPack("wjtp").add(new Transform("wjtp.myTrans", new
> > > SceneTransformer() {
> > > @Override
> > > protected void internalTransform(String phaseName, Map options) {
> > >       CHATransformer.v().transform();
> > >                SootClass a = Scene.v().getSootClass("testers.CallGraphs");
> > >       SootMethod src = Scene.v().getMainClass().getMethodByName("doStuff");
> > >       CallGraph cg = Scene.v().getCallGraph();
> > >       Iterator<MethodOrMethodContext> targets = new
> > > Targets(cg.edgesOutOf(src));
> > >       while (targets.hasNext()) {
> > >           SootMethod tgt = (SootMethod)targets.next();
> > >           System.out.println(src + " may call " + tgt);
> > >       }
> > >       ReachableMethods reachableMethods = new ReachableMethods(cg,
> targets);
> > >       QueueReader<MethodOrMethodContext> transitiveMethods =
> > >       reachableMethods.listener();
> > >       reachableMethods.update();
> > >       System.out.println("Num transitive methods " +
> > > reachableMethods.size());
> > >       while (transitiveMethods.hasNext()) {
> > >       System.out.println(src + " may reach " +
> > > ((SootMethod)transitiveMethods.next()).getName());
> > >       }
> > > }
> > >   }));
> > >            args = argsList.toArray(new String[0]);
> > >            soot.Main.main(args);
> > > }
> > > }
> > > The issue is that I can only see the reachable methods based on the edges
> > > out of method 'doStuff' in class 'CallGraphs'.
> > > I can't see the methods that are reachable transitively, which would be
> > > method 'bar' in class A. I have added in a 'ReachableMethods'
> > > instance based on the call graph and edges from method 'doStuff'. I then
> > > create a QueueReader based on the reachable methods.
> > > However, the queue is empty and also, when I print out
> > > 'reachableMethods.size()', it is 0 for some reason. Any ideas why?
> > > Thanks
> > > JD
> > >
> > > _______________________________________________
> > > Soot-list mailing list
> > > Soot-list at sable.mcgill.ca
> > > http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
> > >
> > >
> >
> >
> >
> > --
> > Dr. Eric Bodden, http://bodden.de/
> > Principal Investigator in Secure Services at CASED
> > Coordinator of the CASED Advisory Board of Study Affairs
> > PostDoc at Software Technology Group, Technische Universität Darmstadt
> > Tel: +49 6151 16-5478    Fax: +49 6151 16-5410
> > Mailing Address: S2|02 A209, Hochschulstraße 10, 64289 Darmstadt

> _______________________________________________
> Soot-list mailing list
> Soot-list at sable.mcgill.ca
> http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list



More information about the Soot-list mailing list