<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><style>body { line-height: 1.5; }blockquote { margin-top: 0px; margin-bottom: 0px; margin-left: 0.5em; }body { font-size: 10.5pt; font-family: 'Microsoft YaHei UI'; color: rgb(0, 0, 0); line-height: 1.5; }</style></head><body>
<div><span></span>Hi Eric,</div><div><br></div><div>Thank you for your prompt reply. </div><div><br></div><div>According to you, I created a class (i.e., com.beust.jcommander.Main) and inserted a main method which calls the <span style="color: rgb(206, 145, 120); font-family: Consolas, 'Courier New', monospace; line-height: 19px; white-space: pre; font-size: 10.5pt; background-color: rgb(30, 30, 30);">parseWithoutValidation</span><span style="line-height: 19px; white-space: pre;"><font> method</font></span><span style="font-size: 10.5pt; line-height: 1.5; background-color: transparent;">. But the call graph is also enpty.  Could you help me with it?</span></div><div><span style="font-size: 10.5pt; line-height: 1.5; background-color: transparent;"><br></span></div><div><span style="font-size: 10.5pt; line-height: 1.5; background-color: transparent;">The code is as follows:</span></div><div><div style="color: rgb(212, 212, 212); font-family: Consolas, 'Courier New', monospace; line-height: 19px; white-space: pre; background-color: rgb(30, 30, 30);"><div><span style="color: #9cdcfe;">Scene</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">loadNecessaryClasses</span>();</div><div><span style="color: #6a9955;">// creat the Main class</span></div><div><span style="color: #9cdcfe;">Scene</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">loadClassAndSupport</span>(<span style="color: #ce9178;">"java.lang.Object"</span>);</div><div><span style="color: #9cdcfe;">Scene</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">loadClassAndSupport</span>(<span style="color: #ce9178;">"java.lang.System"</span>);</div><div><span style="color: #4ec9b0;">SootClass</span> <span style="color: #9cdcfe;">sClass</span> = <span style="color: #c586c0;">new</span> <span style="color: #dcdcaa;">SootClass</span>(<span style="color: #ce9178;">"</span><span style="color: rgb(206, 145, 120); font-size: 10.5pt;">com.beust.jcommander.</span><span style="font-size: 10.5pt; color: rgb(206, 145, 120);">Main"</span><span style="font-size: 10.5pt;">, </span><span style="font-size: 10.5pt; color: rgb(156, 220, 254);">Modifier</span><span style="font-size: 10.5pt;">.</span><span style="font-size: 10.5pt; color: rgb(156, 220, 254);">PUBLIC</span><span style="font-size: 10.5pt;">);</span></div><div><span style="color: #9cdcfe;">sClass</span>.<span style="color: #dcdcaa;">setSuperclass</span>(<span style="color: #9cdcfe;">Scene</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">getSootClass</span>(<span style="color: #ce9178;">"java.lang.Object"</span>));</div><div><span style="color: #9cdcfe;">Scene</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">addClass</span>(sClass);</div><div><span style="color: #6a9955;">// insert a main method</span></div><div><span style="color: #4ec9b0;">SootMethod</span> <span style="color: #9cdcfe;">method</span> = <span style="color: #c586c0;">new</span> <span style="color: #dcdcaa;">SootMethod</span>(<span style="color: #ce9178;">"main"</span>,</div><div>        <span style="color: #9cdcfe;">Arrays</span>.<span style="color: #dcdcaa;">asList</span>(<span style="color: #c586c0;">new</span> <span style="color: #4ec9b0;">Type</span>[] {<span style="color: #9cdcfe;">ArrayType</span>.<span style="color: #dcdcaa;">v</span>(<span style="color: #9cdcfe;">RefType</span>.<span style="color: #dcdcaa;">v</span>(<span style="color: #ce9178;">"java.lang.String"</span>), <span style="color: #b5cea8;">1</span>)}),</div><div>        <span style="color: #9cdcfe;">VoidType</span>.<span style="color: #dcdcaa;">v</span>(), <span style="color: #9cdcfe;">Modifier</span>.<span style="color: #9cdcfe;">PUBLIC</span> | <span style="color: #9cdcfe;">Modifier</span>.<span style="color: #9cdcfe;">STATIC</span>);</div><div><span style="color: #9cdcfe;">sClass</span>.<span style="color: #dcdcaa;">addMethod</span>(method);</div><div>{</div><div>    <span style="color: #4ec9b0;">JimpleBody</span> <span style="color: #9cdcfe;">body</span> = <span style="color: #9cdcfe;">Jimple</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">newBody</span>(method);</div><br><div>    <span style="color: #9cdcfe;">method</span>.<span style="color: #dcdcaa;">setActiveBody</span>(body);</div><div>    <span style="color: #4ec9b0;">Chain</span> <span style="color: #9cdcfe;">units</span> = <span style="color: #9cdcfe;">body</span>.<span style="color: #dcdcaa;">getUnits</span>();</div><div>    <span style="color: #4ec9b0;">Local</span> <span style="color: #9cdcfe;">tmpRef</span>;</div><div>    tmpRef = <span style="color: #9cdcfe;">Jimple</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">newLocal</span>(<span style="color: #ce9178;">"jCommander"</span>, <span style="color: #9cdcfe;">RefType</span>.<span style="color: #dcdcaa;">v</span>(<span style="color: #ce9178;">"com.beust.jcommander.JCommander"</span>));</div><div>    <span style="color: #9cdcfe;">body</span>.<span style="color: #dcdcaa;">getLocals</span>().<span style="color: #dcdcaa;">add</span>(tmpRef);</div><div>        {</div><div>            <span style="color: #4ec9b0;">SootMethod</span> <span style="color: #9cdcfe;">toCall</span> = <span style="color: #9cdcfe;">Scene</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">getMethod</span>(<span style="color: #ce9178;">"<com.beust.jcommander.JCommander: void parseWithoutValidation(java.lang.String[])>"</span>);</div><div>            <span style="color: #9cdcfe;">units</span>.<span style="color: #dcdcaa;">add</span>(<span style="color: #9cdcfe;">Jimple</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">newInvokeStmt</span>(<span style="color: #9cdcfe;">Jimple</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">newVirtualInvokeExpr</span>(tmpRef, <span style="color: #9cdcfe;">toCall</span>.<span style="color: #dcdcaa;">makeRef</span>(), <span style="color: #9cdcfe;">StringConstant</span>.<span style="color: #dcdcaa;">v</span>(<span style="color: #ce9178;">"Hello world!"</span>))));</div><div>        }</div><div>        <span style="color: #9cdcfe;">units</span>.<span style="color: #dcdcaa;">add</span>(<span style="color: #9cdcfe;">Jimple</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">newReturnVoidStmt</span>());</div><div>}</div><div><span style="color: #6a9955;">//custom entry point</span></div><div><span style="color: #4ec9b0;">SootClass</span> <span style="color: #9cdcfe;">c</span> = <span style="color: #9cdcfe;">Scene</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">forceResolve</span>(<span style="color: #ce9178;">"</span><span style="color: rgb(206, 145, 120); font-size: 10.5pt;">com.beust.jcommander.</span><span style="font-size: 10.5pt; color: rgb(206, 145, 120);">Main"</span><span style="font-size: 10.5pt;">, </span><span style="font-size: 10.5pt; color: rgb(156, 220, 254);">SootClass</span><span style="font-size: 10.5pt;">.</span><span style="font-size: 10.5pt; color: rgb(156, 220, 254);">BODIES</span><span style="font-size: 10.5pt;">);</span></div><div><span style="color: #9cdcfe;">c</span>.<span style="color: #dcdcaa;">setApplicationClass</span>();</div><div><span style="color: #4ec9b0;">List</span> <span style="color: #9cdcfe;">entryPoints</span> = <span style="color: #c586c0;">new</span> <span style="color: #dcdcaa;">ArrayList</span>();</div><div><span style="color: #9cdcfe;">entryPoints</span>.<span style="color: #dcdcaa;">add</span>(method);</div><div><span style="color: #9cdcfe;">Scene</span>.<span style="color: #dcdcaa;">v</span>().<span style="color: #dcdcaa;">setEntryPoints</span>(entryPoints);</div></div></div><div><br></div><div><br></div><div>I print the main method:</div><div><div style="color: rgb(212, 212, 212); font-family: Consolas, 'Courier New', monospace; line-height: 19px; white-space: pre; background-color: rgb(30, 30, 30);"><div><span style="color: #569cd6;">public</span> <span style="color: #569cd6;">static</span> <span style="color: #4ec9b0;">void</span> <span style="color: #dcdcaa;">main</span>(<span style="color: #9cdcfe;">java</span>.<span style="color: #9cdcfe;">lang</span>.<span style="color: #9cdcfe;">String</span>[])</div><div>{</div><div>    <span style="color: #4ec9b0;">com</span>.<span style="color: #4ec9b0;">beust</span>.<span style="color: #4ec9b0;">jcommander</span>.<span style="color: #4ec9b0;">JCommander</span> <span style="color: #9cdcfe;">jCommander</span>;</div><br><div>    virtualinvoke jCommander.<<span style="color: #9cdcfe;">com</span>.<span style="color: #9cdcfe;">beust</span>.<span style="color: #9cdcfe;">jcommander</span>.<span style="color: #9cdcfe;">JCommander</span><span style="color: #c586c0;">:</span> <span style="color: #4ec9b0;">void</span> <span style="color: #dcdcaa;">parseWithoutValidation</span>(<span style="color: #9cdcfe;">java</span>.<span style="color: #9cdcfe;">lang</span>.<span style="color: #9cdcfe;">String</span>[])>(<span style="color: #ce9178;">"Hello world!"</span>);</div><br><div>    <span style="color: #c586c0;">return</span>;</div><div>}</div></div></div>
<div><br></div><div><br></div><div>The <span style="color: rgb(220, 220, 170); font-family: Consolas, 'Courier New', monospace; line-height: 19px; white-space: pre; font-size: 10.5pt; background-color: rgb(30, 30, 30);">parseWithoutValidation</span><span style="font-size: 10.5pt; line-height: 1.5; background-color: transparent;">is as follows:</span></div><div><div style="color: rgb(212, 212, 212); font-family: Consolas, 'Courier New', monospace; line-height: 19px; white-space: pre; background-color: rgb(30, 30, 30);"><div><span style="color: #6a9955;">/**</span></div><div><span style="color: #6a9955;">* Parse the command line parameters without validating them.</span></div><div><span style="color: #6a9955;">*/</span></div><div><span style="color: #569cd6;">public</span> <span style="color: #4ec9b0;">void</span> <span style="color: #dcdcaa;">parseWithoutValidation</span>(<span style="color: #4ec9b0;">String</span>... <span style="color: #9cdcfe;">args</span>) {</div><div>    <span style="color: #dcdcaa;">parse</span>(<span style="color: #569cd6;">false</span> <span style="color: #6a9955;">/* no validation */</span>, <span style="color: #9cdcfe;">args</span>);</div><div>}</div></div></div><blockquote style="margin-Top: 0px; margin-Bottom: 0px; margin-Left: 0.5em"><div><br></div><div><br></div><div>Best regards,</div><div>Yuan</div><div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm"><div style="PADDING-RIGHT: 8px; PADDING-LEFT: 8px; FONT-SIZE: 12px;FONT-FAMILY:tahoma;COLOR:#000000; BACKGROUND: #efefef; PADDING-BOTTOM: 8px; PADDING-TOP: 8px"><div><b>From:</b> <a href="mailto:eric.bodden@uni-paderborn.de">Eric Bodden</a></div><div><b>Date:</b> 2020-06-19 04:07</div><div><b>To:</b> <a href="mailto:liuyuan@fastmail.com">liuyuan@fastmail.com</a></div><div><b>CC:</b> <a href="mailto:soot-list@CS.McGill.CA">soot-list</a></div><div><b>Subject:</b> Re: [Soot-list] Why Spark can't obtain the call graph on this snippet?    But CHA can work.</div></div></div><div><div>Hi Yuan.</div>
<div> </div>
<div>I am afraid things are not that simple. The problem is likely the following: Soot will use the method you configured as entry point, but thus is a non-static instance method, which calls other instance methods on “this”. That “this”-object however, has never been initialized by your entry point, thus Spark assumes it to be null - leading to an empty call graph.</div>
<div> </div>
<div>Thus, what we and many others have done in the past is the following: manually create a static mock-up method that properly initializes the object in question (and required helper objects) and then calls parseWithoutValidation. As entry point you then choose this new static mock-up method.</div>
<div> </div>
<div>Sometimes it may make sense to generate such methods automatically. FlowDroid, for instance, does this for Android apps.</div>
<div> </div>
<div>Cheers</div>
<div>Eric</div>
<div> </div>
<div>> On 19. Jun 2020, at 00:16, liuyuan@fastmail.com wrote:</div>
<div>> </div>
<div>> Hi all,</div>
<div>> </div>
<div>> I customizd an entry point for a library (i.e. JCommander, a command interface tool for java) and used the Spark to build its CG. But The callgraph is empty. If I use the CHA, it works. </div>
<div>> </div>
<div>> The code snippet is as follows and the parseWithoutValidation is selected as the entry point.</div>
<div>> public void parseWithoutValidation(String... args) { // the customized entry point</div>
<div>>      parse(false /* no validation */, args); // I think this method could be found easily by Spark~</div>
<div>> }</div>
<div>> </div>
<div>> private void parse(boolean validate, String... args) {</div>
<div>>     StringBuilder sb = new StringBuilder("Parsing \"");</div>
<div>>     sb.append(join(args).append("\"\n  with:").append(join(objects.toArray())));</div>
<div>>     p(sb.toString());</div>
<div>> </div>
<div>>     if (descriptions == null) createDescriptions();</div>
<div>>     initializeDefaultValues();</div>
<div>>     parseValues(expandArgs(args), validate);</div>
<div>>     if (validate) validateOptions();</div>
<div>> }</div>
<div>> </div>
<div>> private StringBuilder join(Object[] args) {</div>
<div>>     StringBuilder result = new StringBuilder();</div>
<div>>     for (int i = 0; i < args.length; i++) {</div>
<div>>         if (i > 0) result.append(" ");</div>
<div>>         result.append(args[i]);</div>
<div>>     }</div>
<div>>     return result;</div>
<div>> }</div>
<div>> ...</div>
<div>> </div>
<div>> My core code is as follows.</div>
<div>> Options.v().set_process_dir(Arrays.asList(classesDir));</div>
<div>> Options.v().set_whole_program(true);</div>
<div>> Options.v().set_no_bodies_for_excluded(true);</div>
<div>> Options.v().set_allow_phantom_refs(true);</div>
<div>> </div>
<div>> // set an entry point</div>
<div>> SootClass c = Scene.v().forceResolve(entryClass, SootClass.BODIES);</div>
<div>> c.setApplicationClass();</div>
<div>> Scene.v().loadNecessaryClasses();</div>
<div>> SootMethod method = c.getMethodByName(entryMethod);</div>
<div>> List entryPoints = new ArrayList();</div>
<div>> entryPoints.add(method);</div>
<div>> Scene.v().setEntryPoints(entryPoints);</div>
<div>> </div>
<div>> //set Spark </div>
<div>> HashMap<String, String> opt = new HashMap<String, String>();</div>
<div>> opt.put("on-fly-cg", "true");</div>
<div>> SparkTransformer.v().transform("", opt);</div>
<div>> PhaseOptions.v().setPhaseOption("cg.spark", "enabled:true");</div>
<div>> </div>
<div>> PackManager.v().runPacks();</div>
<div>> </div>
<div>> The target java file is attached.</div>
<div>> </div>
<div>> Any suggestions are welcome.</div>
<div>> </div>
<div>> Best regards,</div>
<div>> Yuan</div>
<div>> <JCommander.java>_______________________________________________</div>
<div>> Soot-list mailing list</div>
<div>> Soot-list@CS.McGill.CA</div>
<div>> https://mailman.CS.McGill.CA/mailman/listinfo/soot-list</div>
<div> </div>
</div></blockquote>
</body></html>