2017-02-02 10 views
1

У меня есть простая программа, как это:Исключения при попытке инструмента исходного кода по Вал: java.lang.ClassFormatError: StackMapTable ошибка Формата: неправильного размер атрибута

package tests; 

import java.util.Scanner; 

public class TestSum { 

    public static void main(String[] args) { 
     int sum = 0; 
     System.out.print("Please enter starting i: "); 
     int i = new Scanner(System.in).nextInt(); 
     while (i < 11) { 
      sum = sum + i; 
      i = i + 1; 
     } 
     System.out.println("sum = " + sum); 
     System.out.println("Ending i = " + i); 
    } 
} 

Я построил этот код в файл фляги и I хотите использовать WALA для добавления дополнительного инструментального кода для подсчета количества циклов для целей динамического анализа.

Это то, что я сделал с помощью Вала, большинство из питания берется из этого примера Wala Bench Example

import com.ibm.wala.shrikeBT.*; 
import com.ibm.wala.shrikeBT.analysis.Verifier; 
import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder; 
import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; 
import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; 
import com.ibm.wala.shrikeCT.ClassWriter; 

import java.io.BufferedWriter; 
import java.io.FileWriter; 
import java.io.PrintStream; 
import java.io.Writer; 

/** 
* Created by quocnghi on 2/2/17. 
*/ 
public class InstrumentedTest { 
    private final static boolean disasm = true; 

    private final static boolean verify = true; 

    private static OfflineInstrumenter instrumenter = new OfflineInstrumenter(true); 

    public static void main(String[] args) throws Exception { 
     for (int i = 0; i < 1; i++) { 

      Writer w = new BufferedWriter(new FileWriter("report", false)); 

      args = instrumenter.parseStandardArgs(args); 

      instrumenter.setPassUnmodifiedClasses(true); 
      instrumenter.beginTraversal(); 
      ClassInstrumenter ci; 
      while ((ci = instrumenter.nextClass()) != null) { 
       doClass(ci, w); 
      } 
      instrumenter.close(); 
     } 
    } 

    static final String fieldName = "_Bench_enable_trace"; 

    // Keep these commonly used instructions around 
    static final Instruction getSysOut = Util.makeGet(System.class, "out"); 

    static final Instruction callPrintln = Util.makeInvoke(PrintStream.class, "println", new Class[]{String.class}); 

    private static void doClass(final ClassInstrumenter ci, Writer w) throws Exception { 
     final String className = ci.getReader().getName(); 
     System.out.println("Class name : " + className); 
     w.write("Class: " + className + "\n"); 
     w.flush(); 

     for (int m = 0; m < ci.getReader().getMethodCount(); m++) { 
      MethodData d = ci.visitMethod(m); 
      System.out.println(d.getName()); 
      // d could be null, e.g., if the method is abstract or native 
      if (d != null) { 
       w.write("Instrumenting " + ci.getReader().getMethodName(m) + " " + ci.getReader().getMethodType(m) + ":\n"); 
       w.flush(); 

       if (disasm) { 
        w.write("Initial ShrikeBT code:\n"); 
        (new Disassembler(d)).disassembleTo(w); 
        w.flush(); 
       } 

       if (verify) { 
        Verifier v = new Verifier(d); 
        v.verify(); 
       } 

       MethodEditor methodEditor = new MethodEditor(d); 
       methodEditor.beginPass(); 

       final int noTraceLabel = methodEditor.allocateLabel(); 

       IInstruction[] instr = methodEditor.getInstructions(); 
       final String msg0 = "Loop called at " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." 
         + ci.getReader().getMethodName(m); 
       int i = 0; 

       for (IInstruction in : instr) { 
        if (in instanceof ConditionalBranchInstruction) { 

         int b = i; 
         methodEditor.insertBefore(i, new MethodEditor.Patch() { 
          @Override 
          public void emitTo(MethodEditor.Output w) { 
           w.emit(getSysOut); 
           w.emit(ConstantInstruction.makeString(msg0)); 
           w.emit(callPrintln); 
           w.emitLabel(noTraceLabel); 
          } 
         }); 
        } 

        i++; 
        System.out.println(in.toString()); 
       } 
       methodEditor.applyPatches(); 
       if (disasm) { 
        w.write("Final ShrikeBT code:\n"); 
        (new Disassembler(d)).disassembleTo(w); 
        w.flush(); 
       } 
      } 
     } 
     ClassWriter cw = ci.emitClass(); 
     instrumenter.outputModifiedClass(ci, cw); 
    } 
} 

я ожидаю, что после добавления более Instrumented кода, программа должна стать так, что добавить line System.out.println in the loop:

упакованные испытания;

import java.util.Scanner; 

public class TestSum { 

    public static void main(String[] args) { 
     int sum = 0; 
     System.out.print("Please enter starting i: "); 
     int i = new Scanner(System.in).nextInt(); 
     while (i < 11) { 
      sum = sum + i; 
      i = i + 1; 
      System.out.println("One count for this loop"); 
     } 
     System.out.println("sum = " + sum); 
     System.out.println("Ending i = " + i); 
    } 
} 

Но я получил эту ошибку:

java.lang.ClassFormatError: StackMapTable format error: wrong attribute size 

ответ