jakarta-bcel-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stephen Kolaroff <che...@riflexo.com>
Subject Re: Invalid constant pool reference: 28088. Constant pool size is: 1024
Date Thu, 12 Jun 2003 07:56:21 GMT
Kosja, we are strange guys.
Who checked the bug reports?
Nobody...
But should:
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=18323

(I investigated the code. Actually nobody invokes setSize(), when 
reading from file; and NOONE sets proper length of LDC_W, when reading 
from file (i think), and it stays 0 all the time. The fix you made in 
dump() forces dumping with proper length  for the proper instruction).

Strange, I have passed near a MB bytecode through BCEL, and had never 
seen this bug in action.

About method copy:
class Class1 {
void method1() {
// getstatic <System.out>
// ldc #3 <String "Hello world">!!!!!
// invokevirtual <PrintStream::println(String)>
// return
}
}

if you want to copy method1 to _another_ class, you have to make sure 
that ldc "Hello world" points somewhere in the new constantpool where 
you have "Hello world". Complications are pouring in when you want the 
copied method to reference methods of its containing class; or to 
checkcast if a reference points to instance of the enclosing class.

Konstantin Scheglov wrote:

>Hello Stephen,
>
>Wednesday, June 11, 2003, 7:11:16 PM, you wrote:
>
>  Ok, now I am sure, that this is bug in BCEL.
>
>  Here is code from LDC_W:
>  protected void initFromFile(ByteSequence bytes, boolean wide)
>       throws IOException
>  {
>    setIndex(bytes.readUnsignedShort());
>    // Override just in case it has been changed
>    opcode = org.apache.bcel.Constants.LDC_W;
>  }
>  As you can see, it forces instruction code to LDC_W.
>
>  And here is code from LDC:
>  public final void setIndex(int index) {
>    super.setIndex(index);
>    setSize();
>  }
>  protected final void setSize() {
>    if(index <= org.apache.bcel.Constants.MAX_BYTE) { // Fits in one byte?
>      opcode = org.apache.bcel.Constants.LDC;
>      length = 2;
>    } else {
>      opcode = org.apache.bcel.Constants.LDC_W;
>      length = 3;
>    }
>  }
>
>  I.e. setSize() changes inscruction code and length. Then, length
>used in dump() to detect, that byte or short argument is needed:
>  public void dump(DataOutputStream out) throws IOException {
>    out.writeByte(opcode);
>    if(length == 2)
>      out.writeByte(index);
>    else // Applies for LDC_W
>      out.writeShort(index);
>  }
>
>  But we have (in my case) length == 2, i.e. one byte and LDC_W
>instruction! So, when it tryies to create String for this instruction,
>it reads one random byte (in reallity next instruction)!
>
>  When I change dump() to this code, I receive no exceptions.
>
>  public void dump(DataOutputStream out) throws IOException {
>    out.writeByte(opcode);
>    if(opcode == org.apache.bcel.Constants.LDC)
>      out.writeByte(index);
>    else // Applies for LDC_W
>      out.writeShort(index);
>  }
>
>  
>
>SK> The code you sent is OK, at least for BCEL 5.0 and 5.1 (I have 
>SK> experience with those). The problem is elsewere.
>SK> Btw, did you checked if your original (not instrumented) classes are 
>SK> acceptible? It is so stupid mistake, that you have to be genious to 
>SK> avoid it, at least I can not :))).
>SK> Beside this: if you copy method from one class to another (i do not what 
>SK> are your real application), you must change the constant pool indices of 
>SK> the instructions.
>
>SK> Konstantin Scheglov wrote:
>
>  
>
>>> I use following code to instrument one class.
>>> But when I instrument some classes and try to print debug
>>>information, I receive following exception.
>>>
>>>org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference:
28088. Constant pool size is: 1024
>>>       at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
>>>       at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
>>>       at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
>>>       at org.apache.bcel.classfile.Code.toString(Code.java:326)
>>>       at org.apache.bcel.classfile.Code.toString(Code.java:352)
>>>       at java.lang.String.valueOf(String.java:2131)
>>>       at java.io.PrintStream.print(PrintStream.java:462)
>>>       at java.io.PrintStream.println(PrintStream.java:599)
>>>       at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
>>>       at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)
>>>
>>>
>>>As you can see, I just copy code from one method to another (in real application
>>>I change code a little). And when I try to load this class in real application
>>>I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".
>>>
>>>
>>>       public static JavaClass instrumentClass(JavaClass clazz) throws Exception
{
>>>               ClassGen classGen = new ClassGen(clazz);
>>>               ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
>>>               classGen.setConstantPool(cp);
>>>               //
>>>               for (int i = 0; i < clazz.getMethods().length; i++) {
>>>                       Method method = clazz.getMethods()[i];
>>>                       if (method.isAbstract() || method.isNative())
>>>                               continue;
>>>                       if (method.getName().equals("finalize"))
>>>                               continue;
>>>                       MethodGen mg = new MethodGen(method, clazz.getClassName(),
cp);
>>>                       mg.setConstantPool(cp);
>>>                       Method newMethod = mg.getMethod();
>>>                       if (m_Debug) {
>>>                               System.out.println(method.getCode());
>>>                               System.out.println(newMethod.getCode());
>>>                       }
>>>                       classGen.replaceMethod(method, newMethod);
>>>               }
>>>               //
>>>               JavaClass newClazz = classGen.getJavaClass();
>>>               newClazz.setConstantPool(cp.getFinalConstantPool());
>>>               return newClazz;
>>>       }
>>>
>>> What I do wrong?
>>> I see such exception only on few classes (methods).
>>> I have example of such class.
>>>       
>>>
>>> 
>>>
>>>      
>>>
>
>
>
>SK> ---------------------------------------------------------------------
>SK> To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
>SK> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>
>
>
>  
>


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message