-
Bug
-
Resolution: Fixed
-
P2
-
None
-
None
-
JMC 8.0 Sprint 5
Exception Details:
Exception in thread "main" java.lang.VerifyError: Bad local variable type Exception Details: Location: com/tabjy/dining_philosophers/Chopstick.pickUp(Lcom/tabjy/dining_philosophers/Philosopher;J)Z @34: aload_0 Reason: Type top (current frame, locals[0]) is not assignable to reference type Current Frame: bci: @34 flags: { } locals: { top, top, top, top, 'com/tabjy/dining_philosophers/__JFREventChopstickPickUp' } stack: { } Bytecode: 0000000: bb00 2a59 59b7 002b b600 2e3a 042a b400 0000010: 1f20 b200 34b6 0038 9a00 0a03 1904 b600 0000020: 3bac 2a2b b500 3d04 1904 b600 3bac Stackmap Table: full_frame(@34,{Top,Top,Top,Top,Object[#42]},{}) at com.tabjy.dining_philosophers.DiningPhilosophers.main(DiningPhilosophers.java:17)
Post-instrumentation bytecode:
public boolean pickUp(com.tabjy.dining_philosophers.Philosopher, long) throws java.lang.InterruptedException; descriptor: (Lcom/tabjy/dining_philosophers/Philosopher;J)Z flags: (0x0001) ACC_PUBLIC Code: stack=4, locals=5, args_size=3 0: new #42 // class com/tabjy/dining_philosophers/__JFREventChopstickPickUp 3: dup 4: dup 5: invokespecial #43 // Method com/tabjy/dining_philosophers/__JFREventChopstickPickUp."<init>":()V 8: invokevirtual #46 // Method com/tabjy/dining_philosophers/__JFREventChopstickPickUp.begin:()V 11: astore 4 13: aload_0 14: getfield #31 // Field lock:Ljava/util/concurrent/locks/ReentrantLock; 17: lload_2 18: getstatic #52 // Field java/util/concurrent/TimeUnit.MILLISECONDS:Ljava/util/concurrent/TimeUnit; 21: invokevirtual #56 // Method java/util/concurrent/locks/ReentrantLock.tryLock:(JLjava/util/concurrent/TimeUnit;)Z 24: ifne 34 27: iconst_0 28: aload 4 30: invokevirtual #59 // Method com/tabjy/dining_philosophers/__JFREventChopstickPickUp.commit:()V 33: ireturn 34: aload_0 35: aload_1 36: putfield #61 // Field pickedUpBy:Lcom/tabjy/dining_philosophers/Philosopher; 39: iconst_1 40: aload 4 42: invokevirtual #59 // Method com/tabjy/dining_philosophers/__JFREventChopstickPickUp.commit:()V 45: ireturn StackMapTable: number_of_entries = 1 frame_type = 255 /* full_frame */ offset_delta = 34 locals = [ top, top, top, top, class com/tabjy/dining_philosophers/__JFREventChopstickPickUp ] stack = [] LineNumberTable: line 24: 13 line 25: 27 line 28: 34 line 29: 39 LocalVariableTable: Start Length Slot Name Signature 13 33 0 this Lcom/tabjy/dining_philosophers/Chopstick; 13 33 1 philosopher Lcom/tabjy/dining_philosophers/Philosopher; 13 33 2 timeout J Exceptions: throws java.lang.InterruptedException
This bug was discovered while I was coming up with a demo for the agent.
The exact condition triggering this error is yet unclear. I'll keep update once I make new discovery.
Update: the agent generates faulty instrumentation if the original bytecode consists of a "same_frame" frame type.
However, it happens only if original bytecode consists a compressed-frame in the stack map (ie. not a new frame).
update:
The issue is reproducible when the target function consists of multiple exit points, and a compressed stack map frame describing a jump target, followed by a function exit (ie. *return instructions). A simple example could be something like(, given javac writes a compressed frame instead of a new expanded frame):
public int echo(int arg) { if (arg > 42) { return 42; } return arg; }
This may be related to JMC-6532.