[Soot-list] A tricky problem

wqian1 at cs.mcgill.ca wqian1 at cs.mcgill.ca
Mon Feb 7 22:16:29 EST 2005


Hi, everybody:

Today I have encountered a tricky problem. I use two source files from the
Soot Documents "On the Soot menagerie" and "Adding profiling
instructions..." respectively to test the Soot profiling mechanism. But I
have got some exceptions when running:

java Main Menagerie

(Main is the profiling program, and Menagerie is the regular class file)

I got an exception as follows:

Soot started on Mon Feb 07 16:49:04 EST 2005
Transforming Menagerie...
Exception in thread "main" java.lang.RuntimeException: This operation
requires resolving level SIGNATURES but java.io.InterruptedIOException is
at resolving level HIERARCHY
         at soot.SootClass.checkLevel(SootClass.java:123)
         at soot.SootClass.addField(SootClass.java:185)
         at soot.coffi.Util.resolveFromClassFile(Util.java:150)
         at soot.CoffiClassSource.resolve(CoffiClassSource.java:37)
         at soot.SootResolver.bringToHierarchy(SootResolver.java:148)
         at soot.SootResolver.bringToSignatures(SootResolver.java:172)
         at soot.SootResolver.processResolveWorklist(SootResolver.java:104)
         at soot.SootResolver.resolveClass(SootResolver.java:89)
         at soot.Scene.loadClass(Scene.java:329)
         at soot.Scene.loadClassAndSupport(Scene.java:315)
         at GotoInstrumenter.internalTransform(Main.java:131)
         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:547)
         at soot.PackManager.runBodyPacks(PackManager.java:369)
         at soot.PackManager.runPacks(PackManager.java:313)
         at soot.Main.run(Main.java:179)
         at soot.Main.main(Main.java:153)
         at Main.main(Main.java:50)

Who could help me point out the key points of this problem.

Two filesn attached.

Thanks a lot

Weixian Qian

-------------- next part --------------
/* Reference Version: $SootVersion: 1.beta.6.dev.51 $ */

//package ashes.examples.countgotos;

import soot.*;
import soot.jimple.*;
import soot.util.*;
import java.io.*;
import java.util.*;

/** 
   Example to instrument a classfile to produce goto counts. 
 */
public class Main
{    
    public static void main(String[] args) 
    {
        if(args.length == 0)
        {
            System.out.println("Syntax: java ashes.examples.countgotos.Main [soot options]");
            System.exit(0);
        }            
        
        PackManager.v().getPack("jtp").add(new Transform("jtp.instrumenter", GotoInstrumenter.v()));
        soot.Main.main(args);
    }
}

/**
    InstrumentClass example.
    
    Instruments the given class to print out the number of Jimple goto 
    statements executed.

    To enable this class, enable the given PackAdjuster by compiling it 
    separately, into the soot package.
 */

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

    public static GotoInstrumenter v() { return instance; }

    private boolean addedFieldToMainClassAndLoadedPrintStream = false;
    private SootClass javaIoPrintStream;

    private Local addTmpRef(Body body)
    {
        Local tmpRef = Jimple.v().newLocal("tmpRef", RefType.v("java.io.PrintStream"));
        body.getLocals().add(tmpRef);
        return tmpRef;
    }
     
    private Local addTmpLong(Body body)
    {
        Local tmpLong = Jimple.v().newLocal("tmpLong", LongType.v()); 
        body.getLocals().add(tmpLong);
        return tmpLong;
    }

    private void addStmtsToBefore(Chain units, Stmt s, SootField gotoCounter, Local tmpRef, Local tmpLong)
    {
        // insert "tmpRef = java.lang.System.out;" 
        units.insertBefore(Jimple.v().newAssignStmt( 
                      tmpRef, Jimple.v().newStaticFieldRef( 
                      Scene.v().getField("<java.lang.System: java.io.PrintStream out>").makeRef() )), s);

        // insert "tmpLong = gotoCounter;" 
        units.insertBefore(Jimple.v().newAssignStmt(tmpLong, 
                      Jimple.v().newStaticFieldRef(gotoCounter.makeRef() )), s);
            
        // insert "tmpRef.println(tmpLong);" 
        SootMethod toCall = javaIoPrintStream.getMethod("void println(long)");                    
        units.insertBefore(Jimple.v().newInvokeStmt(
                      Jimple.v().newVirtualInvokeExpr(tmpRef, toCall.makeRef(), tmpLong)), s);
    }

    protected void internalTransform(Body body, String phaseName, Map options)
    {
        SootClass sClass = body.getMethod().getDeclaringClass();
        SootField gotoCounter = null;
        boolean addedLocals = false;
        Local tmpRef = null, tmpLong = null;
        Chain units = body.getUnits();
        
        // Add code at the end of the main method to print out the 
        // gotoCounter (this only works in simple cases, because you may have multiple returns or System.exit()'s )
        synchronized(this)
        {
            if (!Scene.v().getMainClass().
                    declaresMethod("void main(java.lang.String[])"))
                throw new RuntimeException("couldn't find main() in mainClass");

            if (addedFieldToMainClassAndLoadedPrintStream)
                gotoCounter = Scene.v().getMainClass().getFieldByName("gotoCount");
            else
            {
                // Add gotoCounter field
                gotoCounter = new SootField("gotoCount", LongType.v(), 
                                                Modifier.STATIC);
                Scene.v().getMainClass().addField(gotoCounter);

                // Just in case, resolve the PrintStream SootClass.
                Scene.v().loadClassAndSupport("java.io.PrintStream");
                javaIoPrintStream = Scene.v().getSootClass("java.io.PrintStream");

                addedFieldToMainClassAndLoadedPrintStream = true;
            }
        }
            
        // Add code to increase goto counter each time a goto is encountered
        {
            boolean isMainMethod = body.getMethod().getSubSignature().equals("void main(java.lang.String[])");

            Local tmpLocal = Jimple.v().newLocal("tmp", LongType.v());
            body.getLocals().add(tmpLocal);
                
            Iterator stmtIt = units.snapshotIterator();
            
            while(stmtIt.hasNext())
            {
                Stmt s = (Stmt) stmtIt.next();

                if(s instanceof GotoStmt)
                {
                    AssignStmt toAdd1 = Jimple.v().newAssignStmt(tmpLocal, 
                                 Jimple.v().newStaticFieldRef(gotoCounter.makeRef() ));
                    AssignStmt toAdd2 = Jimple.v().newAssignStmt(tmpLocal,
                                 Jimple.v().newAddExpr(tmpLocal, LongConstant.v(1L)));
                    AssignStmt toAdd3 = Jimple.v().newAssignStmt(Jimple.v().newStaticFieldRef(gotoCounter.makeRef()), 
                                                                 tmpLocal);

                    // insert "tmpLocal = gotoCounter;"
                    units.insertBefore(toAdd1, s);
                        
                    // insert "tmpLocal = tmpLocal + 1L;" 
                    units.insertBefore(toAdd2, s);

                    // insert "gotoCounter = tmpLocal;" 
                    units.insertBefore(toAdd3, s);
                }
                else if (s instanceof InvokeStmt)
                {
                    InvokeExpr iexpr = (InvokeExpr) ((InvokeStmt)s).getInvokeExpr();
                    if (iexpr instanceof StaticInvokeExpr)
                    {
                        SootMethod target = ((StaticInvokeExpr)iexpr).getMethod();
                        
                        if (target.getSignature().equals("<java.lang.System: void exit(int)>"))
                        {
                            if (!addedLocals)
                            {
                                tmpRef = addTmpRef(body); tmpLong = addTmpLong(body);
                                addedLocals = true;
                            }
                            addStmtsToBefore(units, s, gotoCounter, tmpRef, tmpLong);
                        }
                    }
                }
                else if (isMainMethod && (s instanceof ReturnStmt || s instanceof ReturnVoidStmt))
                {
                    if (!addedLocals)
                    {
                        tmpRef = addTmpRef(body); tmpLong = addTmpLong(body);
                        addedLocals = true;
                    }
                    addStmtsToBefore(units, s, gotoCounter, tmpRef, tmpLong);
                }
            }
        }
    }
}
-------------- next part --------------
/*
 * Created on Feb 7, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

/**
 * @author wqian1
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class Menagerie {
	public static void main(String[] argv) throws Exception{
		int x=2,y=6;
		
		System.out.println("Hi!");
		System.out.println(x*y+y);
		try{
			int z=y*x;
		}catch(Exception e){
			throw e;
		}
	}
}


More information about the Soot-list mailing list