<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.E-MailFormatvorlage17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=DE link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Hi John,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>This happens because the SPARK callgraph builder is context-insensitive. In other words, it does not distinguish the different calling contexts. If the type of a variable x is java.lang.Iterator, a call to x.next() can go out to every implementation of the Iterator interface. If SPARK knows the type of the base variable, it can reduce the number of possible callees – but this is not always the case. Take the following example:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>void foo()  {<o:p></o:p></span></p><p class=MsoNormal style='text-indent:35.4pt'><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Iterator it = myList.iterator();<o:p></o:p></span></p><p class=MsoNormal style='text-indent:35.4pt'><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>doSth(it);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>}<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>void doSth(Iterator it) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>                it.next();<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>}<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>The variable “it” does not have a single specialized type in “doSth” since “doSth” can be called from a variety of places with different actual types for the first argument (and we assume that we’re actually in a larger code base where this happens, so a simple reduction wouldn’t work). The only way to get a more precise call graph would be to track the context: If we came from the call site at line 2 in “foo”, we know that for this call to “doSth” (and only this call), the type of “it” is whatever list iterator we got back in line 1 of “foo”. For some other call to “doSth”, we may have a different actual type.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>In general, there are two ways to solve the issue: Firstly, you can switch to such a context-sensitive callgraph algorithm. Soot supports Paddle which should do the job. Have a look at the command-line reference and the paper on Paddle for the details. Secondly, you can also stay with SPARK and layer context-sensitivity on top. This is what we did in FlowDroid, but which has its own advantages and drawbacks.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>I hope this helps a bit.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Best regards,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>  Steven<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><b><span lang=EN-US style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>Von:</span></b><span lang=EN-US style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> soot-list-bounces@CS.McGill.CA [mailto:soot-list-bounces@CS.McGill.CA] <b>Im Auftrag von </b>John Ng<br><b>Gesendet:</b> Mit</span><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>twoch, 2. September 2015 01:30<br><b>An:</b> soot-list@CS.McGill.CA<br><b>Betreff:</b> [Soot-list] Regarding Call Graph<o:p></o:p></span></p><p class=MsoNormal><o:p>&nbsp;</o:p></p><div><div><p class=MsoNormal>Hello,<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>I have a class as follows:<o:p></o:p></p></div><div><p class=MsoNormal>------------------------<o:p></o:p></p></div><div><p class=MsoNormal>package testers;<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>import java.util.Iterator;<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>public class CallGraphs {<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; Cell[] cells;<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; class Cell {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; private int cell = 0;<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; public Cell(int cell) {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; &nbsp; this.cell = cell;<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; public int getCell() {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; &nbsp; return cell;<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; class CellIterator implements Iterator&lt;Cell&gt; {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; private int idx, end;<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; public CellIterator(int idx, int end) {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; &nbsp; this.idx = idx;<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; &nbsp; this.end = end;<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; public boolean hasNext() {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; &nbsp; return idx &lt; end;<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; public Cell next() {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; &nbsp; return cells[idx++];<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; public void remove() {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; void testIterator() {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; cells = new Cell[5];<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; Cell c0 = new Cell(0);<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; Cell c1 = new Cell(1);<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; Cell c2 = new Cell(2);<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; cells[0] = c0;<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; cells[1] = c1;<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; cells[2] = c2;<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; Iterator&lt;Cell&gt; iterator = new CellIterator(0, 3);<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; while (iterator.hasNext()) {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; &nbsp; Cell c = iterator.next();<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; &nbsp; System.out.println(c.getCell());<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>&nbsp; public static void main(String[] args) {<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; CallGraphs cG = new CallGraphs();<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; &nbsp; cG.testIterator();<o:p></o:p></p></div><div><p class=MsoNormal>&nbsp; }<o:p></o:p></p></div><div><p class=MsoNormal>}<o:p></o:p></p></div><div><p class=MsoNormal>---------------------------------<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>I used Soot to build a call graph for the class. The call graph is exploded because of the method: &lt;testers.CallGraphs$CellIterator: java.lang.Object next()&gt;.&nbsp;<o:p></o:p></p></div><div><p class=MsoNormal>The method &nbsp;&lt;testers.CallGraphs$CellIterator: java.lang.Object next()&gt; is the target method of &lt;testers.CallGraphs$CellIterator: testers.CallGraphs$Cell next()&gt;. The tool reported that this method is called by many other methods such as:<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraints: boolean disables(java.security.Key)&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.misc.ProxyGenerator$ProxyMethod: sun.misc.ProxyGenerator$MethodInfo generateMethod()&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.misc.ProxyGenerator$MethodInfo: void write(java.io.DataOutputStream)&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.misc.ProxyGenerator$ConstantPool: void write(java.io.OutputStream)&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.misc.ProxyGenerator: sun.misc.ProxyGenerator$MethodInfo generateStaticInitializer()&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.misc.ProxyGenerator: sun.misc.ProxyGenerator$MethodInfo generateStaticInitializer()&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.misc.ProxyGenerator: void addProxyMethod(java.lang.reflect.Method,java.lang.Class)&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.security.x509.ExtendedKeyUsageExtension: java.util.List getExtendedKeyUsage()&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;java.security.KeyFactory: java.security.KeyFactorySpi nextSpi(java.security.KeyFactorySpi)&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.misc.ProxyGenerator: void checkReturnTypes(java.util.List)&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.misc.ProxyGenerator: byte[] generateClassFile()&gt;<o:p></o:p></p></div><div><p class=MsoNormal>&lt;sun.misc.ProxyGenerator: byte[] generateClassFile()&gt;<o:p></o:p></p></div><div><p class=MsoNormal>....<o:p></o:p></p></div><div><p class=MsoNormal>            <o:p></o:p></p></div><div><p class=MsoNormal>It seems the result is not correct. Can you let me know how to deal with this case.<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>Thank you very much!&nbsp;<o:p></o:p></p></div><div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div><div><p class=MsoNormal>Best,<o:p></o:p></p></div><div><p class=MsoNormal>John<o:p></o:p></p></div></div></div></body></html>