question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

java.lang.ClassFormatError: StackMapTable format error: bad offset for Uninitialized in method Test.run()V

See original GitHub issue

ClassFormatError happens when advice is applied to a method that

  • has a leading stack frame
  • creates a new value with the first instruction
  • leaves the newly create value uninitialized and performs a jump Seems like bytebuddy inserts an extra nop before original method code and the uninitialized value in stack frame points to that nop instead of the following new instruction.
import static net.bytebuddy.matcher.ElementMatchers.named;

import java.lang.invoke.MethodHandles;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.jar.asm.ClassVisitor;
import net.bytebuddy.jar.asm.ClassWriter;
import net.bytebuddy.jar.asm.Label;
import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.jar.asm.Opcodes;

public class Main implements Opcodes {

  public static void main(String... args) throws Exception {
    new AgentBuilder.Default().type(named("Test"))
            .transform(new AgentBuilder.Transformer.ForAdvice().advice(named("run"), RunnableAdvice.class.getName()))
            .asTerminalTransformation()
            .installOn(ByteBuddyAgent.install());

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    ClassVisitor cv = cw;
    cv.visit(
            V9,
            ACC_PUBLIC | ACC_SUPER,
            "Test",
            null,
            "java/lang/Object",
            new String[] { "java/lang/Runnable" });

    {
      MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
      mv.visitInsn(RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    {
      MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "run", "()V", null, null);
      mv.visitCode();
      Label newInsn = new Label();
      //XXX ClassFormatError does not happen without this line
      mv.visitFrame(F_SAME, 0, null, 0, null);

      mv.visitTypeInsn(NEW, "java/util/ArrayList");
      Label jump = new Label();
      mv.visitJumpInsn(GOTO, jump);
      mv.visitFrame(F_FULL, 0, null, 1, new Object[] { "java/lang/Throwable" });
      mv.visitInsn(NOP);
      mv.visitInsn(NOP);
      mv.visitInsn(NOP);
      mv.visitInsn(ATHROW);
      mv.visitLabel(jump);
      mv.visitFrame(F_FULL, 0, null, 1, new Object[] { newInsn });
      mv.visitInsn(DUP);
      mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false);
      mv.visitVarInsn(ASTORE, 1);
      mv.visitInsn(RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    cv.visitEnd();
    byte[] bytes = cw.toByteArray();
    Class<?> c = MethodHandles.lookup().defineClass(bytes);
    Runnable r = (Runnable) c.getDeclaredConstructor().newInstance();
    r.run();
  }

  public static class RunnableAdvice {

    @Advice.OnMethodEnter(suppress = Throwable.class)
    public static void enter() {
      System.err.println("enter");
    }

    @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
    public static void exit() {
      System.err.println("exit");
    }
  }
}

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
raphwcommented, Sep 20, 2021

My bad, I put the test in a package that Byte Buddy ignores by default.

0reactions
raphwcommented, Sep 21, 2021

Fixed on master.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ASM & Javaagent bytecode instrumentation ... - Stack Overflow
java.lang.ClassFormatError: StackMapTable format error: bad offset for Uninitialized in method org.apache.commons.math.ode.
Read more >
Hello World Plugin - ClassFormatError : StackMapTable ...
When I run the plugin I get the below error. Exception in thread "main" java.lang.ClassFormatError: StackMapTable format error: bad class ...
Read more >
ClassFormatError: StackMapTable format error: bad offset for ...
Coding example for the question ASM & Javaagent bytecode instrumentation: ClassFormatError: StackMapTable format error: bad offset for Uninitialized-Java.
Read more >
[jboss-jira] [JBoss JIRA] (JASSIST-161) java.lang ...
ClassFormatError : StackMapTable format error: bad offset for Uninitialized in method Process._removeFiles_(LProcessFile;)V The intent of the ...
Read more >
java.lang.VerifyError running Daikon with Apache Hadoop
Exception in thread "main" java.lang.ClassFormatError: StackMapTable format error: bad offset for Uninitialized in method org.apache.hadoop.fs.FileSystem.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found