[jboss-jira] [JBoss JIRA] Commented: (JASSIST-99) Javassist causes java.lang.ClassFormatError: Invalid length 561 in LocalVariableTable in class file
Andrew Dinn (JIRA)
jira-events at lists.jboss.org
Fri Jan 29 13:41:28 EST 2010
[ https://jira.jboss.org/jira/browse/JASSIST-99?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12509334#action_12509334 ]
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: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the jboss-jira
mailing list