[Soot-list] about the code coverage

=?GB2312?B?0Oy9oQ==?= fightmyway at gmail.com
Tue Oct 7 16:23:31 EDT 2008


Hi:
qusetion1:
I am using soot to do code coverage. So i modify the code in the tutorial
about profiling. But i find all the two example are use static field to
store the counter. I try to use non-static thing.

en, my way is as the follow: i find i can use blockGraph to get every block
and i find every statement in block will be executed same times. so i try
insert the add counter statement in one block not with every statement which
to be analysis. because one body will have more than one blocks, so i want
to use List to store the counter information of every block and  the print
the list when return statement. After running the program, now i should have
the infomation about how many time every block executing. then i use another
program to get the information about source line number contianed by every
block. So at last, i get the how many times every statement have executed.
en, but i think my way is so complex, has there some easy way?


question2:
i have write the code and use soot to deal with the class which to be
tested. but when i run the class which had been add some instrution, it
report the error like this:
>>>>>xj at xj-laptop:~/workspace/test/sootOutput$ java tester.TestClass
Exception in thread "main" java.lang.VerifyError: (class: tester/TestClass,
method: main signature: ([Ljava/lang/String;)V) Illegal use of nonvirtual
function call
Could not find the main class: tester.TestClass.  Program will exit.
<<<<<
can you give some suggestion?



this is my program

-----------class counter

package profile;

import java.util.ArrayList;
import java.util.List;

public class Counter {
    private List<Integer> blkCnt = new ArrayList<Integer>();


    public synchronized void increase(int blkIdx) {
        if(blkCnt.size() <= blkIdx){
            blkCnt.add(0);
        }
        else {
            int tmp = blkCnt.get(blkIdx);
            tmp++;
            blkCnt.set(blkIdx, tmp);
        }
    }

    public synchronized void report() {
        for (int blkIdx = 0; blkIdx < blkCnt.size(); blkIdx++)
            System.out.println("(" + blkIdx + ": " + blkCnt.get(blkIdx)
                    + ")");
    }
}

-----------------------class convert
package profile;

import java.util.Iterator;
import java.util.Map;

import soot.Body;
import soot.BodyTransformer;
import soot.Local;
import soot.PackManager;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.Transform;
import soot.Unit;
import soot.jimple.IntConstant;
import soot.jimple.InvokeExpr;
import soot.jimple.InvokeStmt;
import soot.jimple.Jimple;
import soot.jimple.ReturnStmt;
import soot.jimple.ReturnVoidStmt;
import soot.toolkits.graph.Block;
import soot.toolkits.graph.BriefBlockGraph;

public class Convert {

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

        PackManager.v().getPack("jtp").add(
                new Transform("jtp.instrumenter", StmtInstrument.v()));
        Scene.v().addBasicClass("profile.Counter",SootClass.SIGNATURES);
        Scene.v().addBasicClass("java.util.ArrayList",SootClass.SIGNATURES);
        soot.Main.main(args);
    }

}


class StmtInstrument extends BodyTransformer {
    private static StmtInstrument instance = new StmtInstrument();

    private StmtInstrument() {
    }

    public static StmtInstrument v() {
        return instance;
    }

    private boolean addedClass = false;
    private SootClass counterClass;
    private SootMethod increaseCounter;
    private SootMethod reportCounter;

    @Override
    protected void internalTransform(Body b, String phaseName, Map options)
{
        // TODO Auto-generated method stub

        synchronized(this)
        {
            if (!Scene.v().getMainClass().
                    declaresMethod("void main(java.lang.String[])"))
                throw new RuntimeException("couldn't find main() in
mainClass");

            if (!addedClass){
                counterClass =
Scene.v().loadClassAndSupport("profile.Counter");
                increaseCounter = counterClass.getMethod("void
increase(int)");
                reportCounter   = counterClass.getMethod("void report()");
                addedClass = true;
            }
        }


        BriefBlockGraph bGraph = new BriefBlockGraph(b);

        int blkNum = bGraph.getBlocks().size();
        Iterator blockIt = bGraph.getBlocks().iterator();
        Local counterLocal = Jimple.v().newLocal("counterRef",
counterClass.getType());
        b.getLocals().add(counterLocal);
        while (blockIt.hasNext()) {
            Block block = (Block) blockIt.next();
            int blkIdx = block.getIndexInMethod();
            InvokeExpr incExpr=
Jimple.v().newSpecialInvokeExpr(counterLocal, increaseCounter.makeRef(),
IntConstant.v(blkIdx));
            InvokeStmt incStmt = Jimple.v().newInvokeStmt(incExpr);
            Unit uh = block.getTail();
            block.insertBefore(incStmt, uh);
            uh.redirectJumpsToThisTo(incStmt);

            if(uh instanceof ReturnStmt || uh instanceof ReturnVoidStmt){
                InvokeExpr repExpr=
Jimple.v().newSpecialInvokeExpr(counterLocal, reportCounter.makeRef());
                InvokeStmt repStmt = Jimple.v().newInvokeStmt(repExpr);
                block.insertBefore(repStmt, uh);
            }
        }
    }
}

-----to be tested class
package tester;
public class TestClass
{
    public static void main(String[] args) {
        System.out.println("helloworld");
    }
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.CS.McGill.CA/pipermail/soot-list/attachments/20081008/ddb93d7b/attachment.htm


More information about the Soot-list mailing list