]
Andrew Dinn commented on JASSIST-99:
------------------------------------
Hi Martin/Chiba,
I've been looking at this issue in a case I have been trying to debug and have got
some way towards resolving it. In my case the problem appears to relate to conversion of
ldc instructions to ldc_w instructions. This is happening in a method which is not itself
explciitly transformed -- the methods which have code explcitly inserted seem to be
updated correctly. n.b. the untransformed method still gets updated under the class
compact operation (called from toBytecode) because the constants pool has been modified to
included more than 256 entries.
Take a look at the attached files before and after (I'll upload them after posting
this note). They contain disassembled bytecode for the offending method getHotelData()
before and after running aopc on the class.
Note that in the after code the start and/or end positions for the entries in the local
variable table are incremented N instructions beyond the correct location wherever the
start and/oror end position is preceded by N ldc_w instructions. This si true in all cases
except for the start position for method parameter 'this' which remains at
position 0. So, for example parameter 'this' has length 170 in the after bytecode
which puts the end position 6 beyond the end of the method and the method contains 6 ldc_w
instructions. Local variable 'roomEntities' has its star position mapped to 97 4
beyond the instruction where it is introduced and its start posiiton follows four ldc_w
instructions. Its end posiiton maps to 170 i.e. once again 6 beyond the end of the
bytecode.
n.b. I believe it is the fact that end positions for some entries exceeds the bytecode
length which trips the error in the verifier.
I am debugging my test case right now and I think I am closing in on where the bug lies. I
will post again when I identify the specific problem.
Javassist causes java.lang.ClassFormatError: Invalid length 561 in
LocalVariableTable in class file
---------------------------------------------------------------------------------------------------
Key: JASSIST-99
URL:
https://jira.jboss.org/jira/browse/JASSIST-99
Project: Javassist
Issue Type: Bug
Affects Versions: 3.11.0.GA
Reporter: Martin Burger
Assignee: Shigeru Chiba
Attachments: after, before, JASSIST-99.zip
I am instrumenting field accesses in Java classes. Unfortunately, this fails in some
cases, the manipulated byte code causes a java.lang.ClassFormatError:
Exception in thread "main" java.lang.ClassFormatError: Invalid length 561 in
LocalVariableTable in class file
de/unisb/cs/st/deltadebugging/jinsi/test/integration/events/outgoing/fieldaccesses/SuperClassOfObserved
at java.lang.ClassLoader.defineClass1(Native Method)
...
This issue occurred in 3.11.0.GA and is not fixed in r505. Maybe this is related to
JASSIST-98. In 3.10.0.GA, this issue does not exist, the affected class can be loaded
without any error.
I tried to analyze the corrupt class file with javassist.tools.framedump, but the
analysis fails:
Exception in thread "main" java.lang.RuntimeException:
javassist.bytecode.BadBytecode: Could not find class in descriptor [pos = 8]:
de.unisb.cs.st.deltadebugging.jinsi.test.integration.events.outgoing.fieldaccesses.Unobserved
at javassist.bytecode.analysis.FramePrinter.print(FramePrinter.java:89)
...
I decompiled both classes (the working one and the corrupt one) using JAD, the output
differs slightly:
43c43
< /* 16*/ JVM INSTR new #96 <Class Long>;
---
> /* 16*/ JVM INSTR new #102 <Class Long>;
59c59
< /* 16*/ JVM INSTR new #96 <Class Long>;
---
> /* 16*/ JVM INSTR new #102 <Class Long>;
Here is the corrupt decompiled code of line 16. Compared to the working class, lines 43
and 59 seem to be switched:
28 /* 16*/ obj = this;
29 /* 16*/ Unobserved unobserved1 = null;
30 /* 16*/ unobserved1 = ((SuperClassOfObserved) (obj)).unobserved;
31 /* 16*/ EventRecorderFactory.getInstance().recordOutgoingFieldRead(this,
JinsiClassUtils.getClassOfObject(this), obj,
Desc.getClazz("de.unisb.cs.st.deltadebugging.jinsi.test.integration.events.outgoing.fieldaccesses.SuperClassOfObserved"),
"unobserved", unobserved1,
Desc.getType("Lde/unisb/cs/st/deltadebugging/jinsi/test/integration/events/outgoing/fieldaccesses/Unobserved;"),
"SuperClassOfObserved.java", 16, Context.METHOD);
32 /* 16*/ EventRecorderFactory.getInstance().recordIncomingFieldRead(this,
JinsiClassUtils.getClassOfObject(this), obj,
Desc.getClazz("de.unisb.cs.st.deltadebugging.jinsi.test.integration.events.outgoing.fieldaccesses.SuperClassOfObserved"),
"unobserved", unobserved1,
Desc.getType("Lde/unisb/cs/st/deltadebugging/jinsi/test/integration/events/outgoing/fieldaccesses/Unobserved;"),
"SuperClassOfObserved.java", 16, Context.METHOD);
33 /* 16*/ obj = unobserved1;
34 /* 16*/ l = 0L;
35 /* 16*/ l = ((Unobserved) (obj)).fieldLong;
36 /* 16*/ EventRecorderFactory.getInstance();
37 /* 16*/ this;
38 /* 16*/ JinsiClassUtils.getClassOfObject(this);
39 /* 16*/ obj;
40 /* 16*/
Desc.getClazz("de.unisb.cs.st.deltadebugging.jinsi.test.integration.events.outgoing.fieldaccesses.Unobserved");
41 /* 16*/ "fieldLong";
42 /* 16*/ l;
43 /* 16*/ JVM INSTR new #102 <Class Long>;
44 /* 16*/ JVM INSTR dup ;
45 /* 16*/ Long();
46 /* 16*/ Desc.getType("J");
47 /* 16*/ "SuperClassOfObserved.java";
48 /* 16*/ 16;
49 /* 16*/ Context.METHOD;
50 /* 16*/ recordOutgoingFieldRead();
51 /* 16*/ JVM INSTR pop ;
52 /* 16*/ EventRecorderFactory.getInstance();
53 /* 16*/ this;
54 /* 16*/ JinsiClassUtils.getClassOfObject(this);
55 /* 16*/ obj;
56 /* 16*/
Desc.getClazz("de.unisb.cs.st.deltadebugging.jinsi.test.integration.events.outgoing.fieldaccesses.Unobserved");
57 /* 16*/ "fieldLong";
58 /* 16*/ l;
59 /* 16*/ JVM INSTR new #102 <Class Long>;
60 /* 16*/ JVM INSTR dup ;
61 /* 16*/ Long();
62 /* 16*/ Desc.getType("J");
63 /* 16*/ "SuperClassOfObserved.java";
64 /* 16*/ 16;
65 /* 16*/ Context.METHOD;
66 /* 16*/ recordIncomingFieldRead();
67 /* 16*/ JVM INSTR pop ;
68 /* 16*/ long fieldLong = l;
However, I don't know if this is related to the defect.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: