[Soot-list] Can't find java.lang.Error
John Jorgensen
jorgnsn at lcd.uregina.ca
Sun Feb 12 00:44:30 EST 2006
>>>>> "mfh02" == Marc Hull (Imperial College) <mfh02 at doc.ic.ac.uk> writes:
mfh02> I've got some code which examines the concrete methods
mfh02> of a class and all superclasses, but it always throws
mfh02> a NullPointerException when retrieving the active body
mfh02> of Object.wait(long, int). This can be recreated
mfh02> using:
mfh02> SootClass sClass =
mfh02> Scene.v().loadClassAndSupport("java.lang.Object");
mfh02> for (Object o : sClass.getMethods()) {
mfh02> SootMethod method = (SootMethod)o;
mfh02> if (method.isConcrete()) {
mfh02> System.out.println(method.getSignature());
mfh02> Body b = method.retrieveActiveBody(); // fails here
mfh02> }
mfh02> }
.
.
.
mfh02> Is this a bug or am I missing some initialisation step which
mfh02> will load the class automatically?
I'm not certain exactly what's going on in your original code,
but in the short example you've provided to reproduce the error,
the problem is indeed the absence of initialisation to load some
classes that Soot needs in order to analyze any code.
I'm not an expert on all the initializations that need to be
performed when using Soot as a library in another application,
rather than via the Soot command line, so I won't try to explain
exactly what's going on, but instead refer you to a previous
thread on soot-list, and to two documents mentioned in that thread:
http://www.sable.mcgill.ca/pipermail/soot-list/2005-March/000172.html
https://svn.sable.mcgill.ca/wiki/index.php/ClassResolver
https://svn.sable.mcgill.ca/wiki/index.php/ClassResolverFAQ
Using information on the two wiki pages, I was able to get your
example to work by changing it to:
public static void main(String[] args) {
Scene.v().addBasicClass("java.lang.Object", SootClass.BODIES);
Scene.v().loadNecessaryClasses();
SootClass sClass =
Scene.v().getSootClass("java.lang.Object");
for (Object o : sClass.getMethods()) {
SootMethod method = (SootMethod)o;
if (method.isConcrete()) {
System.out.println(method.getSignature());
Body b = method.retrieveActiveBody(); // fails here
}
}
}
Depending on what you're doing, it might be easier to write your
code as a new transformation, adding that to some soot "pack",
and then having your application's main() method call
soot.Main.main(). The implementation of soot.tools.CFGViewer
provides a fairly simple application of that technique to add a
BodyTransformer that will get called for each method
processed. I'm not sure if it is possible to add a new
SceneTransformer without modifying soot.PackManager, though.
More information about the Soot-list
mailing list