<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
I'm not an expert, but I think instead of applying specific packs you should use PackManager.v().runPacks();.
<br>
<br>
Also, there's no need to invoke getOrMakeFastHierarchy(), unless you want to use the hierarchy. The hierarchy will be built by the packs if needed. Scene.v().forceResolve() probably isn't required either.</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Best,</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
David Diepenbrock</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Soot-list <soot-list-bounces@CS.McGill.CA> on behalf of Miguel Velez <mvelezce@cs.cmu.edu><br>
<b>Sent:</b> Monday, October 28, 2019 6:41 PM<br>
<b>To:</b> soot-list@cs.mcgill.ca <soot-list@CS.McGill.CA><br>
<b>Subject:</b> [Soot-list] Spark calligraph incomplete</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hi everyone,<br>
<br>
I am trying to build a CallGraph with Spark to called information about what methods call other methods. I am trying to replicated how a CallGraph is built using FlowDroid. However, the call graph that I generate for a program is incomplete. I know it is incomplete
since I compared the number of ClassNodes using ASM (211) with the number of SootClasses from parsing the src and tat of the edges from callGraph.listener() (80). I have spent several hours trying to debug why some edges are missing, but I cannot understand
why.<br>
<br>
Here is how I am building a call graph programmatically:<br>
<br>
```<br>
public static CallGraph buildCallGraph(String entryPoint, String appPath) {<br>
long startTime = System.nanoTime();<br>
initializeSoot(entryPoint, appPath);<br>
<br>
PackManager.v().getPack("wjpp").apply();<br>
PackManager.v().getPack("cg").apply();<br>
<br>
Scene.v().getOrMakeFastHierarchy();<br>
<br>
CallGraph callGraph = Scene.v().getCallGraph();<br>
<br>
long endTime = System.nanoTime();<br>
System.out.println("Time to build call graph: " + ((endTime - startTime) / 1E9));<br>
<br>
return callGraph;<br>
}<br>
<br>
private static void initializeSoot(String entryPoint, String appPath) {<br>
soot.G.reset();<br>
<br>
Options.v().set_no_bodies_for_excluded(true);<br>
Options.v().set_allow_phantom_refs(true);<br>
Options.v().set_output_format(Options.output_format_none);<br>
Options.v()<br>
.set_soot_classpath(<br>
appPath<br>
+ ":/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/jre/lib/jce.jar");<br>
<br>
setSparkOptions();<br>
<br>
Options.v().set_whole_program(true);<br>
Options.v().setPhaseOption("cg", "trim-clinit:false");<br>
Options.v().setPhaseOption("jb.ulp", "off");<br>
Options.v().set_src_prec(Options.src_prec_java);<br>
<br>
// User options<br>
Options.v().setPhaseOption("jb", "use-original-names:true");<br>
<br>
// Options needed for instrumentation<br>
Options.v().set_keep_line_number(true);<br>
Options.v().set_keep_offset(true);<br>
Options.v().set_coffi(true);<br>
Options.v().set_ignore_classpath_errors(true);<br>
<br>
loadClassesAndBodies(entryPoint);<br>
}<br>
<br>
private static void loadClassesAndBodies(String entryPoint) {<br>
Scene.v().addBasicClass(entryPoint, SootClass.BODIES);<br>
Scene.v().loadNecessaryClasses();<br>
<br>
boolean hasClasses = false;<br>
<br>
SootClass c = Scene.v().forceResolve(entryPoint, SootClass.BODIES);<br>
if (c != null) {<br>
c.setApplicationClass();<br>
if (!c.isPhantomClass() && !c.isPhantom()) hasClasses = true;<br>
}<br>
<br>
if (!hasClasses) {<br>
throw new RuntimeException("Only phantom classes loaded, skipping analysis...");<br>
}<br>
}<br>
<br>
private static void setSparkOptions() {<br>
Options.v().setPhaseOption("cg.spark", "on");<br>
Options.v().setPhaseOption("cg.spark", "string-constants:true");<br>
}<br>
```<br>
<br>
Can anyone help me understand what am I doing wrong? <br>
<br>
For instance, this is a method that is part of the calligraphy:<br>
<br>
```<br>
public List<PngPixel> getMergedColors(PngImage image, List<PngPixel> colors, long start) {<br>
for (PngPixel pa : colors) {<br>
if (!pa.isDuplicate()) {<br>
...<br>
}<br>
} <br>
} <br>
```<br>
<br>
but the `isDuplicate()` method is not part of the calligraphy (i.e., the `edgesOutOf(getMergedColors)` does not include `isDuplicate`). However, if I change the class method to:<br>
<br>
```<br>
public List<PngPixel> getMergedColors(PngImage image, List<PngPixel> colors, long start) {<br>
PngPixel pa = new PngPixel();<br>
pa.isDuplicate();<br>
} <br>
```<br>
<br>
The `isDuplicate()` method is part of the call graph. Why would creating a constructor include the method in the call graph?<br>
<br>
Thanks,<br>
<br>
Miguel<br>
_______________________________________________<br>
Soot-list mailing list<br>
Soot-list@CS.McGill.CA<br>
<a href="https://mailman.CS.McGill.CA/mailman/listinfo/soot-list">https://mailman.CS.McGill.CA/mailman/listinfo/soot-list</a><br>
</div>
</span></font></div>
</body>
</html>