title: Exception when trying to instrument source code by WALA: java.lang.ClassFormatError: StackMapTable format error: wrong attribute size
body: <p>I have a simple program like this:</p>
  
  <pre><code>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 &lt; 11 ) {
              sum = sum + i;
              i = i + 1;
          }
          System.out.println("sum = " + sum);
          System.out.println("Ending i = " + i);
      }
  }
  </code></pre>
  
  <p>I built this into a jar file and I want to use WALA to add more instrumented source code to count the number of loop execution for dynamic analysis purpose.</p>
  
  <p>This is what I have done by using Wala, most of the stuffs is taken from this example <a href="https://github.com/wala/WALA/blob/master/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Bench.java" rel="nofollow noreferrer">Wala Bench Example</a></p>
  
  <pre><code>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 &lt; 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 &lt; 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);
      }
  }
  </code></pre>
  
  <p>I expect that after adding more instrumented code, the program should become like this, which add a line System.out.println in the loop :</p>
  
  <p>package tests;</p>
  
  <pre><code>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 &lt; 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);
      }
  }
  </code></pre>
  
  <p>But I got this error : </p>
  
  <pre><code>java.lang.ClassFormatError: StackMapTable format error: wrong attribute size
  </code></pre>