[Soot-list] how does infoFlowAnalysis handle interfaceinvoke ?

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


> Just curious, how do Soot infer this fact?

When Soot creates a call graph it builds points-to sets. Such sets
tell you where objects flow (along assignments) in your program. It
uses this information to determine which of the many polymorphic call
targets can actually be called at a call site. If the points-to set is
empty this means that either the call site is unreachable or the call
target will be null and therefore you will see no call edges. See
Ondrej's thesis if you are interested in details, it has very easy to
follow descriptions:
http://www.sable.mcgill.ca/publications/thesis/#olhotakPhDThesis

>> hw.tmp.hw3tmp will always be null, at the call site
>> "tmp.hw3tmp.open3();" the points-to set of "tmp.hw3tmp" will be empty
>
> I use cg.cha to build the most over approximated call graph, so there
> should be no points-to set here(?).

Yes, CHA is much simpler. It only looks at the class hierarchy, and
uses no points-to sets. That makes it faster but much less precise as
you can see in your example.

Eric

>
> Jiangfan
>
>>
>>
>>>
>>> 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
>>
>



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


More information about the Soot-list mailing list