From deb3d52fec87690fed1a14aa4f8666a59f0fcc14 Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Mon, 21 Jun 2004 16:52:14 +0000 Subject: [PATCH] ObjectOutputStream.java: Add DEBUG statements everywhere. 2004-06-21 Andrew Haley * java/io/ObjectOutputStream.java: Add DEBUG statements everywhere. (dumpElementln): New method. (depth): New field. * java/io/ObjectInputStream.java (currentClassLoader): Make native. (callersClassLoader): New field. (depth): New field. (readObject): ENDBLOCKDATA is generated if the class has a write method, not if it has a read method. (readObject): Save and restore this.currentObject and this.currentObjectStreamClass around calls to callReadMethod(). * java/io/natObjectInputStream.cc (getCallersClassLoader): New method. From-SVN: r83440 --- libjava/ChangeLog | 17 +++++ libjava/java/io/ObjectInputStream.java | 87 +++++++++++++++++-------- libjava/java/io/ObjectOutputStream.java | 64 ++++++++++++++++-- libjava/java/io/natObjectInputStream.cc | 32 +++++++++ 4 files changed, 170 insertions(+), 30 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index b77c9a90a98..a08f217de68 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,20 @@ +2004-06-21 Andrew Haley + + * java/io/ObjectOutputStream.java: Add DEBUG statements + everywhere. + (dumpElementln): New method. + (depth): New field. + * java/io/ObjectInputStream.java + (currentClassLoader): Make native. + (callersClassLoader): New field. + (depth): New field. + (readObject): ENDBLOCKDATA is generated if the class has a write + method, not if it has a read method. + (readObject): Save and restore this.currentObject and + this.currentObjectStreamClass around calls to callReadMethod(). + * java/io/natObjectInputStream.cc (getCallersClassLoader): New + method. + 2004-06-18 Andreas Tobler * testsuite/libjava.jni/jni.exp (gcj_jni_test_one): Add lgcc_s for diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java index 9747699a562..292f841a657 100644 --- a/libjava/java/io/ObjectInputStream.java +++ b/libjava/java/io/ObjectInputStream.java @@ -38,20 +38,24 @@ exception statement from your version. */ package java.io; -import gnu.classpath.Configuration; -import gnu.java.io.ObjectIdentityWrapper; - import java.lang.reflect.Array; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; +import java.security.PrivilegedAction; +import java.security.AccessController; import java.util.Arrays; import java.util.Hashtable; import java.util.Vector; +import gnu.java.io.ObjectIdentityWrapper; +import gnu.java.lang.reflect.TypeSignature; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + +import gnu.classpath.Configuration; + public class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants { @@ -120,6 +124,15 @@ public class ObjectInputStream extends InputStream */ public final Object readObject() throws ClassNotFoundException, IOException { + if (callersClassLoader == null) + { + callersClassLoader = getCallersClassLoader (); + if (Configuration.DEBUG && dump) + { + dumpElementln ("CallersClassLoader = " + callersClassLoader); + } + } + if (this.useSubclassMethod) return readObjectOverride(); @@ -134,6 +147,9 @@ public class ObjectInputStream extends InputStream this.isDeserializing = true; byte marker = this.realInputStream.readByte(); + + depth += 2; + if(dump) dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " "); try @@ -151,9 +167,9 @@ public class ObjectInputStream extends InputStream case TC_BLOCKDATALONG: { if (marker == TC_BLOCKDATALONG) - if(dump) dumpElementln("BLOCKDATALONG"); + { if(dump) dumpElementln("BLOCKDATALONG"); } else - if(dump) dumpElementln("BLOCKDATA"); + { if(dump) dumpElementln("BLOCKDATA"); } readNextBlock(marker); throw new StreamCorruptedException("Unexpected blockData"); } @@ -319,6 +335,9 @@ public class ObjectInputStream extends InputStream Object obj = newObject(clazz, osc.firstNonSerializableParent); int handle = assignNewHandle(obj); + Object prevObject = this.currentObject; + ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass; + this.currentObject = obj; ObjectStreamClass[] hierarchy = inputGetObjectStreamClasses(clazz); @@ -341,34 +360,42 @@ public class ObjectInputStream extends InputStream boolean oldmode = setBlockDataMode(true); callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj); setBlockDataMode(oldmode); + } + else + { + readFields(obj, currentObjectStreamClass); + } + + if (this.currentObjectStreamClass.hasWriteMethod()) + { if(dump) dumpElement("ENDBLOCKDATA? "); try { - // FIXME: XXX: This try block is to catch EOF which is - // thrown for some objects. That indicates a bug in the logic. + // FIXME: XXX: This try block is to + // catch EOF which is thrown for some + // objects. That indicates a bug in + // the logic. + if (this.realInputStream.readByte() != TC_ENDBLOCKDATA) throw new IOException ("No end of block data seen for class with readObject (ObjectInputStream) method."); if(dump) dumpElementln("yes"); } - catch (EOFException e) - { - if(dump) dumpElementln("no, got EOFException"); - } +// catch (EOFException e) +// { +// if(dump) dumpElementln("no, got EOFException"); +// } catch (IOException e) { if(dump) dumpElementln("no, got IOException"); } } - else - { - readFields(obj, currentObjectStreamClass); - } } - this.currentObject = null; - this.currentObjectStreamClass = null; + this.currentObject = prevObject; + this.currentObjectStreamClass = prevObjectStreamClass; ret_val = processResolution(osc, obj, handle); + break; } @@ -397,6 +424,8 @@ public class ObjectInputStream extends InputStream this.isDeserializing = was_deserializing; + depth -= 2; + if (! was_deserializing) { if (validators.size() > 0) @@ -710,7 +739,7 @@ public class ObjectInputStream extends InputStream protected Class resolveClass(ObjectStreamClass osc) throws ClassNotFoundException, IOException { - return Class.forName(osc.getName(), true, currentLoader()); + return Class.forName(osc.getName(), true, callersClassLoader); } /** @@ -1802,11 +1831,9 @@ public class ObjectInputStream extends InputStream * @param sm SecurityManager instance which should be called. * @return The current class loader in the calling stack. */ - private static ClassLoader currentClassLoader (SecurityManager sm) - { - // FIXME: This is too simple. - return ClassLoader.getSystemClassLoader (); - } + private static native ClassLoader currentClassLoader (SecurityManager sm); + + private native ClassLoader getCallersClassLoader(); private void callReadMethod (Method readObject, Class klass, Object obj) throws IOException { @@ -1864,6 +1891,11 @@ public class ObjectInputStream extends InputStream private static boolean dump = false && Configuration.DEBUG; + private ClassLoader callersClassLoader; + + // The nesting depth for debugging output + private int depth = 0; + private void dumpElement (String msg) { System.out.print(msg); @@ -1872,6 +1904,9 @@ public class ObjectInputStream extends InputStream private void dumpElementln (String msg) { System.out.println(msg); + for (int i = 0; i < depth; i++) + System.out.print (" "); + System.out.print (Thread.currentThread() + ": "); } static diff --git a/libjava/java/io/ObjectOutputStream.java b/libjava/java/io/ObjectOutputStream.java index b60f3b6a100..cc77976b492 100644 --- a/libjava/java/io/ObjectOutputStream.java +++ b/libjava/java/io/ObjectOutputStream.java @@ -144,6 +144,13 @@ public class ObjectOutputStream extends OutputStream protocolVersion = defaultProtocolVersion; useSubclassMethod = false; writeStreamHeader(); + + if (Configuration.DEBUG) + { + String val = System.getProperty("gcj.dumpobjects"); + if (val != null && !val.equals("")) + dump = true; + } } /** @@ -172,10 +179,18 @@ public class ObjectOutputStream extends OutputStream { if (useSubclassMethod) { + if (dump) + dumpElementln ("WRITE OVERRIDE: " + obj); + writeObjectOverride(obj); return; } + if (dump) + dumpElementln ("WRITE: " + obj); + + depth += 2; + boolean was_serializing = isSerializing; boolean old_mode = setBlockDataMode(false); try @@ -318,6 +333,8 @@ public class ObjectOutputStream extends OutputStream if (obj instanceof Serializable) { + Object prevObject = this.currentObject; + ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass; currentObject = obj; ObjectStreamClass[] hierarchy = ObjectStreamClass.getObjectStreamClasses(clazz); @@ -329,17 +346,25 @@ public class ObjectOutputStream extends OutputStream fieldsAlreadyWritten = false; if (currentObjectStreamClass.hasWriteMethod()) { + if (dump) + dumpElementln ("WRITE METHOD CALLED FOR: " + obj); setBlockDataMode(true); callWriteMethod(obj, currentObjectStreamClass); setBlockDataMode(false); realOutput.writeByte(TC_ENDBLOCKDATA); + if (dump) + dumpElementln ("WRITE ENDBLOCKDATA FOR: " + obj); } else + { + if (dump) + dumpElementln ("WRITE FIELDS CALLED FOR: " + obj); writeFields(obj, currentObjectStreamClass); } + } - currentObject = null; - currentObjectStreamClass = null; + this.currentObject = prevObject; + this.currentObjectStreamClass = prevObjectStreamClass; currentPutField = null; break; } @@ -360,12 +385,22 @@ public class ObjectOutputStream extends OutputStream setBlockDataMode(false); try { + if (Configuration.DEBUG) + { + e.printStackTrace(System.out); + } writeObject(e); } catch (IOException ioe) { - throw new StreamCorruptedException - ("Exception " + ioe + " thrown while exception was being written to stream."); + StreamCorruptedException ex = + new StreamCorruptedException + (ioe + " thrown while exception was being written to stream."); + if (Configuration.DEBUG) + { + ex.printStackTrace(System.out); + } + throw ex; } reset (true); @@ -375,6 +410,10 @@ public class ObjectOutputStream extends OutputStream { isSerializing = was_serializing; setBlockDataMode(old_mode); + depth -= 2; + + if (dump) + dumpElementln ("END: " + obj); } } @@ -1171,6 +1210,9 @@ public class ObjectOutputStream extends OutputStream field_name = fields[i].getName(); type = fields[i].getType(); + if (dump) + dumpElementln ("WRITE FIELD: " + field_name + " type=" + type); + if (type == Boolean.TYPE) realOutput.writeBoolean(getBooleanField(obj, osc.forClass(), field_name)); else if (type == Byte.TYPE) @@ -1512,6 +1554,14 @@ public class ObjectOutputStream extends OutputStream return m; } + private void dumpElementln (String msg) + { + for (int i = 0; i < depth; i++) + System.out.print (" "); + System.out.print (Thread.currentThread() + ": "); + System.out.println(msg); + } + // this value comes from 1.2 spec, but is used in 1.1 as well private final static int BUFFER_SIZE = 1024; @@ -1534,6 +1584,12 @@ public class ObjectOutputStream extends OutputStream private int protocolVersion; private boolean useSubclassMethod; + // The nesting depth for debugging output + private int depth = 0; + + // Set if we're generating debugging dumps + private boolean dump = false; + static { if (Configuration.INIT_LOAD_LIBRARY) diff --git a/libjava/java/io/natObjectInputStream.cc b/libjava/java/io/natObjectInputStream.cc index bb3796ff4fa..9da4910aa06 100644 --- a/libjava/java/io/natObjectInputStream.cc +++ b/libjava/java/io/natObjectInputStream.cc @@ -19,6 +19,8 @@ details. */ #include #include #include +#include +#include #ifdef DEBUG #include @@ -69,3 +71,33 @@ java::io::ObjectInputStream::callConstructor (jclass klass, jobject obj) + m->offset); _Jv_CallAnyMethodA (obj, JvPrimClass (void), meth, false, arg_types, NULL); } + +java::lang::ClassLoader* +java::io::ObjectInputStream::getCallersClassLoader () +{ + java::lang::ClassLoader *loader = NULL; + gnu::gcj::runtime::StackTrace *t + = new gnu::gcj::runtime::StackTrace(4); + java::lang::Class *klass = NULL; + try + { + for (int i = 2; !klass; i++) + { + klass = t->classAt (i); + } + loader = klass->getClassLoaderInternal(); + } + catch (::java::lang::ArrayIndexOutOfBoundsException *e) + { + // FIXME: RuntimeError + } + + return loader; +} + +java::lang::ClassLoader* +java::io::ObjectInputStream::currentClassLoader (::java::lang::SecurityManager *sm) +{ + return sm->currentClassLoader (); +} + -- 2.30.2