[Soot-list] Loading class and support: problem instrumenting bytecode

Eric Bodden eric.bodden at mail.mcgill.ca
Fri Jun 13 12:20:20 EDT 2008


Hi Luca.

loadClassAndSupport(..) is not the default way (any more) to load
classes into Soot. Can you try something like this?

   public static void main(String[] args)
   {
       if(args.length == 0)
       {
           System.out.println("Syntax: MyMain [soot options]");
           System.exit(0);
       }

       PackManager.v().getPack("jtp").add(new
Transform("jtp.instrumenter", GotoInstrumenter.v()));

       // Just in case, resolve the PrintStream and System soot-classes
       Scene.v().addBasicClass("java.io.PrintStream",SootClass.SIGNATURES);
       Scene.v().addBasicClass("java.lang.System",SootClass.SIGNATURES);
       soot.Main.main(args);
   }

So before you call soot.Main.main(args) you instruct Soot to load
"java.lang.System" to SIGNATURES level. You have to use
"instrumenter.utils.UnitInstrumentation" there of course ;-)

Eric


2008/6/13 Luca Cavallaro <mitch_ing at yahoo.it>:
- Show quoted text -
> Dear all,
> I have a question about loading classes with soot at run time.
> I am trying to instrument bytecode using an external helper static method.
> Actually I want to add the call to this method after some statements are
> executed.
> I am trying to implement this thing in a body transformer which I want to
> insert in the jtp pack.
> The problem is that whe I try to load the class that contains the method I
> want to call I get this exception:
>
> java.lang.RuntimeException: This operation requires resolving level SIGNATURES
> but instrumenter.utils.UnitInstrumentation is at resolving level HIERARCHY
>        at soot.SootClass.checkLevel(SootClass.java:126)
>        at soot.SootClass.addMethod(SootClass.java:581)
>        at soot.coffi.Util.resolveFromClassFile(Util.java:252)
>        at soot.CoffiClassSource.resolve(CoffiClassSource.java:37)
>        at soot.SootResolver.bringToHierarchy(SootResolver.java:148)
>        at soot.SootResolver.bringToSignatures(SootResolver.java:172)
>        at soot.SootResolver.bringToBodies(SootResolver.java:214)
>        at soot.SootResolver.processResolveWorklist(SootResolver.java:100)
>        at soot.SootResolver.resolveClass(SootResolver.java:89)
>        at soot.Scene.loadClass(Scene.java:329)
>        at soot.Scene.loadClassAndSupport(Scene.java:314)
>        at
> instrumenter.transformation.MethodInstrumenter.internalTransform(MethodInstrumenter.java:30)
>        at soot.BodyTransformer.transform(BodyTransformer.java:51)
>        at soot.Transform.apply(Transform.java:104)
>        at soot.BodyPack.internalApply(BodyPack.java:50)
>        at soot.Pack.apply(Pack.java:120)
>        at soot.PackManager.runBodyPacks(PackManager.java:681)
>        at soot.PackManager.runBodyPacks(PackManager.java:396)
>        at soot.PackManager.runBodyPacks(PackManager.java:340)
>        at soot.PackManager.runPacks(PackManager.java:335)
>        at soot.Main.run(Main.java:203)
>        at soot.Main.main(Main.java:146)
>        at instrumenter.transformation.Main.main(Main.java:21)
>
>
> Here is the code I am trying to use for instrumentation:
> protected void internalTransform(Body b, String phaseName, Map options) {
>
>                SootClass sc =
> Scene.v().loadClassAndSupport("instrumenter.utils.UnitInstrumentation");
>                SootMethod unitInstrumenter = sc.getMethodByName("myMethod");
>                SootMethod m = b.getMethod();
>                ExceptionalUnitGraph eg = new ExceptionalUnitGraph(b);
>                List<Unit> methodHeads = eg.getHeads();
>                PatchingChain units = m.getActiveBody().getUnits();
>                for(Unit head: methodHeads){
>                        instrumentUnit(eg, units, head, unitInstrumenter);
>                }
>
>                Iterator<Unit> overMethodUnits = units.snapshotIterator();
>                while(overMethodUnits.hasNext()){
>                        Unit next = overMethodUnits.next();
>
>                        if(next instanceof IfStmt || next instanceof ThrowStmt || next instanceof
> GotoStmt||next instanceof ReturnStmt||next instanceof ThrowStmt){
>                                instrumentUnit(eg, units, next, unitInstrumenter);
>
>                        }
>
>                }
>
>        }
>
>        private void instrumentUnit(ExceptionalUnitGraph eg, PatchingChain units,
>                        Unit next, SootMethod unitInstrumenter) {
>
>                Vector<Unit> v = new Vector<Unit>();
>                List<Unit> l = eg.getSuccsOf(next);
>                for(Unit u : l){
>
>                        v.add(u);
>                        InvokeExpr expr =
> Jimple.v().newStaticInvokeExpr(unitInstrumenter.makeRef(),v);
>                        Stmt incStmt = Jimple.v().newInvokeStmt(expr);
>                        units.insertAfter(incStmt, u);;
>                }
>        }
>
> These are the options I am trying to pass to soot.Main:
> -p cg.spark on  -cp ${soot-cp2}:
> ${instrumentationcp}:/usr/lib/jvm/java-1.5.0-sun-1.5.0.11/jre/lib//jce.jar:/usr/lib/jvm/java-1.5.0-sun-1.5.0.11/jre/lib/rt.jar:/home/luca/universita/dottorato/minore/eclipse/plugins/org.aspectj.runtime_1.6.0.20081300000002/aspectjrt.jar -f
> jimple -w -i instrumenter --app examples.lollypop.Factory --output-dir
> jimpleout
>
> Naturally the class whose method I want to invoke has been included in soot
> class path, as wellas the Factory class (that is the one I want to
> instrument).
>
> Anyone has a hint?
> Thank you very much
> Luca
> _______________________________________________
> Soot-list mailing list
> Soot-list at sable.mcgill.ca
> http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
>



--
Eric Bodden
Sable Research Group
McGill University, Montréal, Canada


More information about the Soot-list mailing list