[Soot-list] how does infoFlowAnalysis handle interfaceinvoke ?

Eric Bodden eric.bodden at mail.mcgill.ca
Tue Aug 19 10:09:13 EDT 2008


I think you are misunderstanding something here...

> The missing edge is from the start() method in the helloworld class to
> the open3() method in the interface myInter. Furthermore, there maybe
> missing edges from the start() to the open3() methods in the two
> implementations of myInter, which are myinter1.java and myinter2.java.

There is supposed to be no edge, for the following reason. In main you
have the call sequence...

              helloworld3 hw33=new helloworld3();
              helloworld hw=new helloworld(hw33);
              hw.start();

This initializes the object referenced by hw and the field hw.tmp.
However, you *never* call setup(...) on hw.tmp. Therefore
hw.tmp.hw3tmp will always be null, at the call site
"tmp.hw3tmp.open3();" the points-to set of "tmp.hw3tmp" will be empty
and therefore you will (correctly) see no outgoing call edges: If you
were to reach this call at runtime then you would see a
NullPointerException (but in fact you would not even reach it, due to
the null check preceding the call).

I bet that if you change the above three lines to ...

              helloworld3 hw33=new helloworld3();
              helloworld hw=new helloworld(hw33);
              hw33.setup(new myinter1());
              hw.start();

... then you will see your call edge.

Eric


>
> The point here is that in the helloworld3 class, its' field hw3tmp
> maybe instantiated with any of two implementations of the myInter in
> the setup(myInter mi) method. So the method start() should be linked
> to these open3() methods in these two implementations.
>
> If you encounter any execution problem, just let me know.
>
> Thanks.
>
> Jiangfan
>
> In case we can not attach a file to the mail list. I put all source
> files in the following:
>
>
> ============cg exploration===============
> package mytransformer;
>
> import soot.*;
>
> import java.io.BufferedWriter;
> import java.io.FileWriter;
> import java.util.*;
>
> import soot.jimple.toolkits.callgraph.*;
>
> public class TestMyTransformer extends SceneTransformer {
>
>        public static void main(String[] args) {
>                if (args.length == 0)
>                        System.exit(-1);
>                PackManager.v().getPack("wjtp").add(
>                                new Transform("wjtp.mytransform", TestMyTransformer.v()));
>                soot.Main.main(args);
>        }
>
>        private static TestMyTransformer instance = null;
>
>        public static TestMyTransformer v() {
>                if (instance == null)
>                        return (instance = new TestMyTransformer());
>                return instance;
>        }
>
>        protected void internalTransform(String phaseName, Map options) {
>                CallGraph cg = Scene.v().getCallGraph();
>                System.out.println("Call graph + " + cg);
>        }
>
>        public void writetofile(CallGraph cg) {
>                try {
>                        // Create file
>                        FileWriter fstream = new FileWriter("out22.txt");
>                        BufferedWriter out = new BufferedWriter(fstream);
>                        out.write(cg.toString());
>                        // Close the output stream
>                        out.close();
>                } catch (Exception e) {// Catch exception if any
>                        System.err.println("Error: " + e.getMessage());
>                }
>        }
>
> }
>
> =======main class helloworld ====
> package hello;
> public class helloworld {
>       helloworld3 tmp;
>
>       helloworld(helloworld3 hw3){
>               tmp=hw3;
>       }
>
>       public void start(){
>               System.out.println("start");
>
>               if(tmp.hw3tmp!=null)
>                       tmp.hw3tmp.open3();
>       }
>
>       public static void main(String[] args){
>
>               helloworld3 hw33=new helloworld3();
>               helloworld hw=new helloworld(hw33);
>               hw.start();
>       }
> }
>
> class helloworld3 {
>       myInter hw3tmp;
>
>       helloworld3(){
>               hw3tmp=null;
>       }
>
>       void setup(myInter mi){
>               hw3tmp=mi;
>       }
> }
>
> =======Interface myInter ====
> package hello;
> public interface myInter {
>       public void open3();
>
> }
> ==========One implementation impl1========
> package hello;
> public class myinter1 implements myInter{
>       public void open3(){
>               System.out.println("myinter1");
>
>       }
> }
> ==========One implementation impl2========
> package hello;
> public class myinter2 implements myInter {
>
>       public void open3() {
>               // TODO Auto-generated method stub
>               System.out.println("myinter2");
>       }
>
> }
>
> ==============source code over===================
>
>
>
> On Tue, Aug 19, 2008 at 7:50 AM, Eric Bodden <eric.bodden at mail.mcgill.ca> wrote:
>> Hi.
>>
>> Which call edge exactly do you find missing from the example below? I
>> need a concrete and complete runnable example to be able to decide if
>> this is or is not a bug.
>>
>> Eric
>>
>> 2008/8/18 jiangfan shi <jiangfan.shi at gmail.com>:
>>> Thanks, Li xin.
>>>
>>> I have tried to use spark and cha (default option) to construct the
>>> call graph. As you said, the generated call graph does not have
>>> related interfaceInvoke edges. That is, there is not edge which
>>> connects the main function to impl1.open() or impl2.open(). And even,
>>> there is no edge between the main function and the interface
>>> Inter1.open().
>>>
>>> My options are following:
>>>
>>> spark:
>>>
>>> -w -main-class helloworld -p cg.spark rta:true;on-fly-cg:true -f
>>> jimple --app helloworld
>>>
>>> cha:
>>>
>>> -w -main-class helloworld -p cg.cha on -f jimple --app helloworld
>>>
>>> The following is my simplifiedcode.
>>>
>>> =======main class helloworld ====
>>>
>>> public class helloworld {
>>>        helloworld3 tmp;
>>>
>>>        helloworld(helloworld3 hw3){
>>>                tmp=hw3;
>>>        }
>>>
>>>        public void start(){
>>>                System.out.println("start");
>>>
>>>                if(tmp.hw3tmp!=null)
>>>                        tmp.hw3tmp.open3();
>>>        }
>>>
>>>        public static void main(String[] args){
>>>
>>>                helloworld3 hw33=new helloworld3();
>>>                helloworld hw=new helloworld(hw33);
>>>                hw.start();
>>>        }
>>> }
>>>
>>> =============Another Class helloworld3============
>>> class helloworld3 {
>>>        myInter hw3tmp;
>>>
>>>        helloworld3(){
>>>                hw3tmp=null;
>>>        }
>>>
>>>        void setup(myInter mi){
>>>                hw3tmp=mi;
>>>        }
>>> }
>>>
>>> =======Interface myInter ====
>>> public interface myInter {
>>>        public void open3();
>>>
>>> }
>>> ==========One implementation impl1========
>>>
>>> public class myinter1 implements myInter{
>>>        public void open3(){
>>>                System.out.println("myinter1");
>>>
>>>        }
>>> }
>>> ==========One implementation impl2========
>>>
>>> public class myinter2 implements myInter {
>>>
>>>        public void open3() {
>>>                // TODO Auto-generated method stub
>>>                System.out.println("myinter2");
>>>        }
>>>
>>> }
>>>
>>> Any ideas? Thanks.
>>> Jiangfan
>>>
>>>
>>>
>>> On Mon, Aug 18, 2008 at 9:35 AM, li xin <li-xin at jaist.ac.jp> wrote:
>>>> Hello,
>>>>
>>>> I am wondering it is the issue of whether the underlying points-to analysis
>>>> properly handle InterfaceInvoke.
>>>>
>>>> FYI:
>>>> This question reminds me a related problem I ever encountered. I run
>>>> cg.spark (with default options on mind) on some package, but edges of
>>>> InterfaceInvoke are lost in the generated call graph (while CHA handles them
>>>> properly).
>>>>
>>>>
>>>> --
>>>> Thanks and Best Regards, LI
>>>>
>>>> On Mon, Aug 18, 2008 at 10:45 PM, jiangfan shi <jiangfan.shi at gmail.com>
>>>> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> I found the infoFlowAnalysis does not do dynamic bindings for the
>>>>> interfaceinvoke statement. Am I right?
>>>>>
>>>>> For exmaple, I have an interface Interf1, which defines a method
>>>>> open(). Two implementations impl1 and impl2 implement the Interf1.
>>>>> Then I have following simplified statements;
>>>>>
>>>>> ==============
>>>>> Interf1 tmp1;
>>>>>
>>>>> if(tmp1!=null){
>>>>>      tmp1.open().
>>>>> }
>>>>>
>>>>> ==============
>>>>>
>>>>> For this piece of code, the infoFlowAnalysis does not give two
>>>>> possible method invocations, impl1.open() and impl2.open().
>>>>> Furthermore the infoFlowAnalysis does not compute flow Summary for
>>>>> these two methods.
>>>>>
>>>>> For the following piece of code, the infoFlowAnalysis does work
>>>>> because there are explicitly assignments from impl1 or impl2 to the
>>>>> Interf1.
>>>>>
>>>>> ==============
>>>>> Interf1 tmp1;
>>>>> if(args[0]=1){
>>>>>     tmp1=new impl1();
>>>>> else
>>>>>     tmp1=new impl2();
>>>>>
>>>>> tmp1.open().
>>>>> }
>>>>>
>>>>> ==============
>>>>> In this case, the infoFlowAnalysis will compute summaries for the two
>>>>> methods,  impl1.open() and impl2.open().
>>>>>
>>>>> So my question is that if the infoFlowAnalysis handle the
>>>>> interfaceinvoke statement. Maybe I did not find some configurations of
>>>>> the infoFlowAnalsysis, or I miss some other options.
>>>>>
>>>>> Thanks you in advance!
>>>>>
>>>>> Jiangfan
>>>>> _______________________________________________
>>>>> Soot-list mailing list
>>>>> Soot-list at sable.mcgill.ca
>>>>> http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
>>>>
>>>>
>>>>
>>> _______________________________________________
>>> Soot-list mailing list
>>> Soot-list at sable.mcgill.ca
>>> http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
>>>
>>
>>
>>
>> --
>> Eric Bodden
>> Sable Research Group
>> McGill University, Montréal, Canada
>>
>



-- 
Eric Bodden
Sable Research Group
McGill University, Montréal, Canada


More information about the Soot-list mailing list