An introduction to Soot 2.2.5
Soot is a program analysis and transformation framework for Java, developed at the Sable Research Group of McGill University, but with contributions by other researchers from all over the world.
Release 2.2.5 contains some exciting new features, for example:
- Manu Sridharan’s demand-driven refinement-based context-sensitive points-to analysis, based on Spark
- a new Thread-local objects analysis, which Halpert et al. used for automatic lock allocation
- an improved version of our nullness analysis, due to Julian Tibble, and
- Instance Keys, static representatives of runtime objects.
Furthermore there have been several improvements to the Soot Eclipse plugin to enhance its ease of use.
Soot Eclipse plugin
Installation
To install the latest version of the plugin, start Eclipse and click on:
Help -> Software Updates -> Find and Install
Select Search new features to install and add a new remote site for this URL:
http://www.sable.mcgill.ca/soot/eclipse/updates/
Select the newly created remote site and the Discovery Site for your Eclipse version. Then click Finish.
Select the Soot plugin form the list. If eclipse complains that it cannot find Draw2D or GEF, also select Graphical Editors and Frameworks from the Eclipse Discovery Site.
Click Ok and restart Eclipse.
Using the plugin
Assume that we want to use the Soot plugin to analyze the Testclass shown in the figure.
public class Testclass {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
String string = args[i];
System.err.println(string);
}
}
}
We therefore right-click on the source file and select :
Soot -> Process Source File -> Run Soot…
We further wish to visualize the data flow analysis that Soot performs. In the dialog we therefore enable the Interactive Mode.
In result, Soot will show you for each method it analyzes the method’s control flow graph, along with the analysis information that is computed. In the figure we see results for the load-store optimizer (as indicated by the console output).
Extending Soot (by Example)
Extending Soot is easy and now we even provide concrete Examples within Eclipse. Click
File -> New -> Example..
and select one of the examples, e.g. A simple BodyTransformer.
Soot will create a new Java project to host the example. Enter all necessary information for the project.
Eclipse will then automatically show the example file.
Note that the file accesses types like PackManager which are part of the Soot library. How does the project get access to that library? The Soot plugin automatically provides the build path variable SOOTCLASSES that points to soot’s library. For example projects, this variable is added automatically. If you want to extend Soot without using an example project you can just add the variable by yourself. (right-click on your project and select BuildPath)
Assume now that we want to apply our new BodyTransformer to the Testclass class, as before. Again, right-click on Testclass.java and select, as before:
Soot -> Process Source File -> Run Soot…
Only this time select the Soot Main Class tab and set the values as shown in the Figure. This advises the plugin to start Soot by calling MyMain in project MyBodyTranformer. The console view will now show that the customized BodyTransformer executed.






Hi Eric,
Thanks for these nice posts about SOOT. I am beginning to use SOOT for some
simple data flow analysis in my research (I am trying to do a PhD in CS at
University of Delaware, USA)
I used SOOT to do the reaching def analysis and got expected results. I have a doubt
about the following:
public int m1() // in a class C1
{
init();
return field1; // field is an integer field in the C1
}
private void init()
{
field1 = 5;
}
the above assignment provides a definition for field1 that reaches the return
statement in m1(). The default Jimple Annotation pack reaching def
did not show this (though I did select inter-procedure and entire program
mode). Am I missing something here?
Thanks a lot!
Giri
Hi. Very good question. The answer is simple, though: the reaching-definitions analysis in Soot is intra-procedural, which means that it does not consider outgoing method calls like the one from m1() to init(). What you are looking for is an inter-procedural RD analysis, but to the best of my knowledge Soot does not come with such an analysis out-of-the box.
Eric
Vielen Dank! Eric. I will explore the survivor’s guide to see how inter-procedural
analysis can be added (if I see the need for it)
Best Wishes
Giri
Hi Eric,
I am sorry to trouble you again, but I did not find a suitable answer in the
survivor’s guide or the PLDI tutorial slides etc.
My issue is with reaching defs. Soot does intra-procedural reaching defs. But what
exactly does it do when it encounters a method call?
Ex:
1 area = initialize();
2 area = computeArea();
3 print (area);
4 return area;
Soot tells (correctly) that the def on line 2 (but not line 1) reaches line 4. BUT how
did it know that line 3 did not assign to area? (assume area is a field or
can be changed within print)
Thanks
Giri
Hi Giri.
I assume that you are talking about SmartLocalDefs, used by the ReachingDefsTagger? If so, then the following holds: SmartLocalDefs gives you the reaching definitions of local variables. When
areais a local variable then print(…) obviously cannot write to it. Local variables can only be written to within the local method. They are, effectively, stack locations. Your advisor Lori is right in the case whereareais a field, but SimpleLocalDefs only gives information for local variables. Hope that clarifies things…Eric
Hi Eric,
A small continuation of the doubt in my previous comment.
The simple reaching def tagger that comes off the shelf with soot, simply ignores
outgoing calls? Is that correct behaviour? My advisor Lori Pollock told me that conservatively a reaching def tagger must warn
you that the value could be modified within the call (please see the example)
Thanks
Giri
Hi, Eric
I want to associate jimple ConditionExpr to source code conditions in compound predicate. I have seen the same question before. You said if we run soot on source code, the line number information could be used. I guess you mean that if serveral jimple ConditionExprs have the same line number, then they belong to the same compound predicate. However, if the compound predicate spans mutiple lines in the source code, this method would not work, because in this case conditions in the same compound predicate may correspond to ConditionExprs with different line numbers. Perhaps, one way to handle this case is to preprocess the source code to make sure that one predicate spans only one line. But when it comes to run soot on class file, this would not work again. I was wondering if there is any other easy way provided by soot to handle this problem?
Thank you very much!
Sihan
Hi Sihan.
I am afraid you have already analyzed the problem and possible solutions quite thoroughly. The only complete approach I see to this problem is to modify Soot’s Java source-code frontent.
Eric
Hi Eric,
Thanks for your information. I guess I have to use the line number information to solve the problem now.
Sihan
Hi Eric,
Thank you for these valuable posts which are very useful to me.
I am trying to do some inter-procedural dataflow analysis. Now I have a question. If a program has no main method, that means there is no entry point in the program(such as JDK collection library code). Can I get the call graph of the program?
Thanks so much.
Hi Zuo.
Without a main method this is not so simple. After all, which calls should Soot consider? How will the library be used? In the past people have often use stubs, i.e., artificial main methods for this purpose. This is still a largely unsolved problem…
Eric
Hi Eric,
Thanks for your reply. I’ll think about it.
Zhiqiang
Hi,
I looking for a way of capturing coverage of java bytecode for statement and branch at first. Followed by dataflow coverage. I just came across Soot. I would like to capture the coverage data while running Junit tests. Do you know if Soot could collect this data, if so, how would I do it.
Thanks in advanced
Mark
Hi Mark. This could certainly be done. You would just need to instrument statements/branches or individual paths with the desired logging code. This tutorial may be of help to you:
http://www.sable.mcgill.ca/soot/tutorial/profiler/index.html
Eric
Eric,
Thanks for that. I work though the tutorial and see how it goes..
Thanks once again.
Eric,
I can transform java source files to numerious different sort outputs i.e. class, jasmin, baf, jimple etc. I been trying to work though the example ‘Creating a class from scratch with Soot’. However, when I try and compile the code example with – javac Main.java, I get a list of errors that would appear to relate the the soot imports. I using Soot 2.4. I sure I doing something silly.
Thanks in advanced.
Eric,
I have managed to resolve of the above and compile and run the Adding profiling instructions to applications with soot. Do you have a specification of the statement types generated by Jimple so I can catch them to ensure I have achieved statement coverage.
Thanks in advanced.
Hi Mark.
You can find a grammar for Jimple here:
https://svn.sable.mcgill.ca/soot/soot/trunk/src/jimple.scc
However, it may be easiest to use a StmtSwitch:
http://www.sable.mcgill.ca/soot/doc/soot/jimple/StmtSwitch.html
This is effectively a visitor that allows you to implement one method for each statement kind.
Eric
Hi Eric,
I’m using the soot to analyze the java program. Now is it possible to determine whether a stmt(Jimple) may throw exceptions(not including errors)?
Thanks
zhiqiang
Hello.
Sure, please have a look at soot.toolkits.exceptions.ThrowAnalysis. This should give you the appropriate information.
Eric
Hi Eric,
Actually I have tried the subclass UnitThrowAnalysis, and used the mightThrow(stmt). But i found it’s not exactly what i want.
For instance, there is a Jimple invokeStmt:
virtualinvoke temp$4.(i);
I’d like to get exceptions which this invokestmt may throw. While the mightThrow() will return all the Throwable exceptions, which means this stmt may throw any type exception. So it seems not accurate enough.
Am i right or there’s something wrong with my understanding?
Thanks
Would you mind posting this question on the Soot mailing list? Maybe somebody else can help you out there. I have never used UnitThrowAnalysis personally, and hence cannot comment on how accurate it is. It may well be the case, though, that the analysis is conservative and just reports “anything” because it does not analyze the callee method(s).
Thanks for your reply.
Hi Eric,
I’m trying to use soot to generate a call graph for an application. The problem is that the call graph having 3 application classes with 2 methods in each, the size of the call graph is 169578 and this mainly because there are a lot of Java library methods included. is there a way to generate the call graph without including certain library classes? I a few words, I only need to have access to a call graph which contains only the methods of the classes I’m analysing and no other methods.
Thanks in advance
Hi Clarissa.
Yes that’s possible (although potentially unsound):
http://www.bodden.de/2010/06/04/soot-no-jdk/
Cheers,
Eric
Thanks for the reply. I’ve tried it and it worked… at least now the edges are down to 226. I excluded the “java.” package, however, there are still methods in the graph which are in the java.lang package which are present in the call graph. Is there a way to exclude them as well or they still have to remain in the call graph?
thanks
Hi Eric,
I am using SOOT to generate a call graph. The call graph is in fact being generated, however the nodes for private methods are not being included in the call graph, and I cannot get the target methods for these methods.
I excluded the classes in the .java package and I also included the “-no-bodies-for-excluded”, and this lead to private methods not being included in the call graph. However when I removed this exclusion, all nodes were returned.
Is there a way to be able to solve this problem, i.e. be able to get nodes in the call graph for private methods, but still exclude .java nodes from the call graph please?
Thanks a lot
Hi.
Normally the options you mention should have absolutely no impact on call resolution private methods. Can you post a minimal example to the Soot mailing list? That should give us a chance to find out what’s going on.
Eric
Hey eric,
I would like to use SOOT to generate call graphs for my programs.Will constructors will be included also in the graph by any chance? I tried looking it up but I could not find such information.
Thanks,
sarah
Hi Sarah.
Yes. Constructors are actually just special methods in Java. Soot will treat them like any other method.
Eric
Hey Eric,
thanks for the reply, Is this explained anywhere please… I’ve read “A Survivor’s Guide to
Java Program Analysis with Soot” and it does not mention this anywhere. I created a call graph but till now I only got the init as a target method.
thanks,
Sarah, init *is* the constructor! They are labeled with init internally (in the bytecode as well as in Jimple).
Eric
ohh ok thanks a lot for your help :)
Hi Eric,
I am using SOOT for my project. I have written my own analysis extending forward-flow analysis. Let us consider the below statement.
int value = a.getValue();
where a is an instance of class ‘A’ and getValue() is an instance method
The jimple code generated for the above statement is
temp$1 = virtualinvoke a.; //JAssignmentStatement
value = $temp1;
But, during my program execution,
temp$1 = virtualinvoke a. statement (of type JAssignmentStatement) is not actually analyzed in the flowThrough method (of my forwardFlowAnalysis).
Instead, virtualinvoke a. (without the assignment and just JVirtualInvoke statement) is analyzed.
I am not sure why its considering the above JAssignmentStatement as just JVirtualInvoke statement. Any help in this issue would be greatly appreciated.
Thanks in advance.
Hi Eric,
I am facing an issue with SOOT. Any help in this issue would be greatly appreciated.
I am using SOOT for my project. I have written my own analysis extending forward-flow analysis. Let us consider the below statement.
int value = a.getValue();
where a is an instance of class ‘A’ and getValue() is an instance method
The jimple code generated for the above statement is
temp$1 = virtualinvoke a.getValue(); //JAssignment statement
value = $temp1;
But, during my program execution,
temp$1 = virtualinvoke a.getValue() statement (of type JAssignmentStatement) is not actually analyzed in the flowThrough() method (of my forwardFlowAnalysis).
Instead, virtualinvoke a.getValue() (without the assignment and just JVirtualInvoke statement) is analyzed.
I am not sure why its considering the above JAssignmentStatement as just JVirtualInvoke statement.
Thanks in advance.
Hello. Sorry about the late response.
I am afraid your description does not make much sense to me. I think you must be misinterpreting something. Soot analyzes the Jimple statement that are part of the SootMethod’s body. It should be all consistent.