[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Constructing Call graphs without java.* classes



Dear Ondrej,

First of all, thanks for your answer! I was already looking into the Filter class in the call-graph API, in case there was no way of excluding specific calls from the graph construction process... With answer make me sure about how to deal with the problem.

Based on what you said, I have another question. In my program, if I try to access the call graph (from the Scene object) without using the parameter "-W", soot gives me a warning and tells me that there is no call-graph. So, can I assume that in order access the call graph I need to use the "-W" option?

I am asking that because I am concerned with the processing time that Soot requires. Without the "-W" option, soot processes the HelloWorld program in about 6 seconds. However, with it, soot requires about 2 minutes to do it. So, if in order to create a call graph I always need to run the "-W" option, I will have to find some way to deal with this processing time. For the record, I understand that creating the call-graph is a time-consuming task, I just want to make sure that I am not missing anything important.

Thanks again for your help,

cleidson de souza


Ondrej Lhotak wrote:


The -x option affects which classes are considered application classes
when Soot is run with the -app switch. However, for the purposes of call
graph construction, the complete call graph is always constructed. There
are no command-line options to exclude specific calls from the call
graph.

Probably the easiest way to achieve what you are trying to do is to
filter out the unwanted methods from the call graph when you are
printing it out. On each method, you can call getDeclaringClass() to get
its class, and decide based on the class whether to print the method or
not. You can do this by either parsing the package name yourself, or by
just calling isApplicationClass(). This will return true if the class
was mentioned on the command-line, or, when the -app switch is given, if
the class is not one of the library classes excluded by the -x switch.

Ondrej

On Sat, Feb 21, 2004 at 10:20:40AM -0800, Cleidson Ronald Botelho de Souza wrote:

Hi all,

I am new to this list and to the Soot framework, so I apologize if I am sending a too basic question to this list. First of all, let
me tell you my interest: I am interested in using the Soot framework to create call-graphs of Java programs. Soot, with this community and continuos improvement seems very appropriate for me. Thanks for the great work !


Anyway, I've already spent some time playing with Soot and with its call-graph API. Indeed, a friend and I wrote the very simple code that is attached. The code basically runs on a "HellowWorld.java" program and creates a call-graph for it, which is later printed out.

However, I am facing a problem: the CallGraph is created but includes Nodes that represent methods calls to classes in the following packages: java.* and sun.*. And I am NOT interested in those. For the record, a simple "HelloWorld.java" program is going to have about 6084 nodes, while only 4 of them are relevant (i.e., from the HelloWorld program).

I've tried several different set of parameters, including "-x java" as explained in the manual, but nothing seems to work. According to the manual, I should NOT need this, because those classes were not supposed to be included in the call-graph.


Any ideas?

Thanks in advance,

cleidson rb de souza

A pessimist sees the difficulty in every opportunity; an optimist sees the opportunity in every difficulty. " Winston Churchill, Sir (1874-1965)"


import java.util.Iterator;
import java.util.List;

import soot.*;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.tagkit.Tag;

public class SootTest {

public static void main(String args[]) {

String strClass = "HelloWorld";

				//strClass is used here and also as the last param in the opts array
				SootClass sootClass = Scene.v().loadClassAndSupport(strClass);

				//just seeing what some of the functions do... looks like its reading in the file correctly
				System.out.println("Number of methods in " + sootClass.getName() + ": " + sootClass.getMethodCount());
				// String[] opts = {"-W", "-app", "-f", "jimple", "-p", "jb", "use-original-names:true", "-p", "cg.spark", "on", "-p", "cg.spark",
				//				"simplify-offline:true","-p", "cg.spark","on-fly-cg:true", "-p", "tag.ln","enabled:true",
                               //"-keep-line-number", strClass};
				 String [] opts = {"-W", "-keep-line-number", strClass };
				// String[] opts = {"-w", strClass};

				//have to set the application class
				System.out.println("Set Application classes");
				sootClass.setApplicationClass();
				Scene.v().setMainClass(sootClass);

				//set the options to the static main class
				System.out.println("Set options to the static main class");
				Main.main(opts);
				System.out.println("Get the call graph");

				//get the call graph
				CallGraph cg = Scene.v().getCallGraph();
				if(cg==null){
						System.out.println("Call graph is equal to null, exiting!");
				}else{
						System.out.println("Call graph is non null, analyzing");
						analyze(cg);
				}
		}

	public static void analyze(CallGraph cg){
			 int i = 0;

			 //print out what we've got.
			 for(Iterator iter = cg.sourceMethods(); iter.hasNext();){
					 SootMethod sootMethod = (SootMethod)iter.next();
					 System.out.println(i + " " + sootMethod.getName());
					 if(sootMethod.hasActiveBody()){
							 Body body = sootMethod.getActiveBody();
							 System.out.println("\t Active Body: "+body);
					 }else{
							 System.out.println("\t No Active Body Found!");
					 }

					 System.out.println("\t Byte Code Signature: "+sootMethod.getBytecodeSignature());
					 System.out.println("\t Declaration: "+sootMethod.getDeclaration());
					 System.out.println("\t Declaring Class: "+sootMethod.getDeclaringClass());
					 System.out.println("\t Modifiers: "+sootMethod.getModifiers());
					 System.out.println("\t Parameter Count: "+sootMethod.getParameterCount());
					 System.out.println("\t Return Type: "+sootMethod.getReturnType());
					 System.out.println("\t Signature: "+sootMethod.getSignature());
					 System.out.println("\t Sourhce: "+sootMethod.getSource());
					 List listTags = sootMethod.getTags();
					 if(listTags!=null){
							 for(int j=0; j<listTags.size(); j++){
									 Tag tag = (Tag) listTags.get(i);
									 System.out.println("\t\tTag " +j+" " +tag.getName());
							 }
					 }
					   i++;
				}

		}
}