Commit deb3d52f by Andrew Haley Committed by Andrew Haley

ObjectOutputStream.java: Add DEBUG statements everywhere.

2004-06-21  Andrew Haley  <aph@redhat.com>

	* 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
parent 413ed876
2004-06-21 Andrew Haley <aph@redhat.com>
* 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 <a.tobler@schweiz.ch> 2004-06-18 Andreas Tobler <a.tobler@schweiz.ch>
* testsuite/libjava.jni/jni.exp (gcj_jni_test_one): Add lgcc_s for * testsuite/libjava.jni/jni.exp (gcj_jni_test_one): Add lgcc_s for
......
...@@ -38,20 +38,24 @@ exception statement from your version. */ ...@@ -38,20 +38,24 @@ exception statement from your version. */
package java.io; package java.io;
import gnu.classpath.Configuration;
import gnu.java.io.ObjectIdentityWrapper;
import java.lang.reflect.Array; 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.Modifier;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.security.PrivilegedAction;
import java.security.AccessController;
import java.util.Arrays; import java.util.Arrays;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Vector; 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 public class ObjectInputStream extends InputStream
implements ObjectInput, ObjectStreamConstants implements ObjectInput, ObjectStreamConstants
{ {
...@@ -120,6 +124,15 @@ public class ObjectInputStream extends InputStream ...@@ -120,6 +124,15 @@ public class ObjectInputStream extends InputStream
*/ */
public final Object readObject() throws ClassNotFoundException, IOException public final Object readObject() throws ClassNotFoundException, IOException
{ {
if (callersClassLoader == null)
{
callersClassLoader = getCallersClassLoader ();
if (Configuration.DEBUG && dump)
{
dumpElementln ("CallersClassLoader = " + callersClassLoader);
}
}
if (this.useSubclassMethod) if (this.useSubclassMethod)
return readObjectOverride(); return readObjectOverride();
...@@ -134,6 +147,9 @@ public class ObjectInputStream extends InputStream ...@@ -134,6 +147,9 @@ public class ObjectInputStream extends InputStream
this.isDeserializing = true; this.isDeserializing = true;
byte marker = this.realInputStream.readByte(); byte marker = this.realInputStream.readByte();
depth += 2;
if(dump) dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " "); if(dump) dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " ");
try try
...@@ -151,9 +167,9 @@ public class ObjectInputStream extends InputStream ...@@ -151,9 +167,9 @@ public class ObjectInputStream extends InputStream
case TC_BLOCKDATALONG: case TC_BLOCKDATALONG:
{ {
if (marker == TC_BLOCKDATALONG) if (marker == TC_BLOCKDATALONG)
if(dump) dumpElementln("BLOCKDATALONG"); { if(dump) dumpElementln("BLOCKDATALONG"); }
else else
if(dump) dumpElementln("BLOCKDATA"); { if(dump) dumpElementln("BLOCKDATA"); }
readNextBlock(marker); readNextBlock(marker);
throw new StreamCorruptedException("Unexpected blockData"); throw new StreamCorruptedException("Unexpected blockData");
} }
...@@ -319,6 +335,9 @@ public class ObjectInputStream extends InputStream ...@@ -319,6 +335,9 @@ public class ObjectInputStream extends InputStream
Object obj = newObject(clazz, osc.firstNonSerializableParent); Object obj = newObject(clazz, osc.firstNonSerializableParent);
int handle = assignNewHandle(obj); int handle = assignNewHandle(obj);
Object prevObject = this.currentObject;
ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
this.currentObject = obj; this.currentObject = obj;
ObjectStreamClass[] hierarchy = ObjectStreamClass[] hierarchy =
inputGetObjectStreamClasses(clazz); inputGetObjectStreamClasses(clazz);
...@@ -341,34 +360,42 @@ public class ObjectInputStream extends InputStream ...@@ -341,34 +360,42 @@ public class ObjectInputStream extends InputStream
boolean oldmode = setBlockDataMode(true); boolean oldmode = setBlockDataMode(true);
callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj); callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
setBlockDataMode(oldmode); setBlockDataMode(oldmode);
}
else
{
readFields(obj, currentObjectStreamClass);
}
if (this.currentObjectStreamClass.hasWriteMethod())
{
if(dump) dumpElement("ENDBLOCKDATA? "); if(dump) dumpElement("ENDBLOCKDATA? ");
try try
{ {
// FIXME: XXX: This try block is to catch EOF which is // FIXME: XXX: This try block is to
// thrown for some objects. That indicates a bug in the logic. // catch EOF which is thrown for some
// objects. That indicates a bug in
// the logic.
if (this.realInputStream.readByte() != TC_ENDBLOCKDATA) if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
throw new IOException throw new IOException
("No end of block data seen for class with readObject (ObjectInputStream) method."); ("No end of block data seen for class with readObject (ObjectInputStream) method.");
if(dump) dumpElementln("yes"); if(dump) dumpElementln("yes");
} }
catch (EOFException e) // catch (EOFException e)
{ // {
if(dump) dumpElementln("no, got EOFException"); // if(dump) dumpElementln("no, got EOFException");
} // }
catch (IOException e) catch (IOException e)
{ {
if(dump) dumpElementln("no, got IOException"); if(dump) dumpElementln("no, got IOException");
} }
} }
else
{
readFields(obj, currentObjectStreamClass);
}
} }
this.currentObject = null; this.currentObject = prevObject;
this.currentObjectStreamClass = null; this.currentObjectStreamClass = prevObjectStreamClass;
ret_val = processResolution(osc, obj, handle); ret_val = processResolution(osc, obj, handle);
break; break;
} }
...@@ -397,6 +424,8 @@ public class ObjectInputStream extends InputStream ...@@ -397,6 +424,8 @@ public class ObjectInputStream extends InputStream
this.isDeserializing = was_deserializing; this.isDeserializing = was_deserializing;
depth -= 2;
if (! was_deserializing) if (! was_deserializing)
{ {
if (validators.size() > 0) if (validators.size() > 0)
...@@ -710,7 +739,7 @@ public class ObjectInputStream extends InputStream ...@@ -710,7 +739,7 @@ public class ObjectInputStream extends InputStream
protected Class resolveClass(ObjectStreamClass osc) protected Class resolveClass(ObjectStreamClass osc)
throws ClassNotFoundException, IOException 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 ...@@ -1802,11 +1831,9 @@ public class ObjectInputStream extends InputStream
* @param sm SecurityManager instance which should be called. * @param sm SecurityManager instance which should be called.
* @return The current class loader in the calling stack. * @return The current class loader in the calling stack.
*/ */
private static ClassLoader currentClassLoader (SecurityManager sm) private static native ClassLoader currentClassLoader (SecurityManager sm);
{
// FIXME: This is too simple. private native ClassLoader getCallersClassLoader();
return ClassLoader.getSystemClassLoader ();
}
private void callReadMethod (Method readObject, Class klass, Object obj) throws IOException private void callReadMethod (Method readObject, Class klass, Object obj) throws IOException
{ {
...@@ -1864,6 +1891,11 @@ public class ObjectInputStream extends InputStream ...@@ -1864,6 +1891,11 @@ public class ObjectInputStream extends InputStream
private static boolean dump = false && Configuration.DEBUG; 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) private void dumpElement (String msg)
{ {
System.out.print(msg); System.out.print(msg);
...@@ -1872,6 +1904,9 @@ public class ObjectInputStream extends InputStream ...@@ -1872,6 +1904,9 @@ public class ObjectInputStream extends InputStream
private void dumpElementln (String msg) private void dumpElementln (String msg)
{ {
System.out.println(msg); System.out.println(msg);
for (int i = 0; i < depth; i++)
System.out.print (" ");
System.out.print (Thread.currentThread() + ": ");
} }
static static
......
...@@ -144,6 +144,13 @@ public class ObjectOutputStream extends OutputStream ...@@ -144,6 +144,13 @@ public class ObjectOutputStream extends OutputStream
protocolVersion = defaultProtocolVersion; protocolVersion = defaultProtocolVersion;
useSubclassMethod = false; useSubclassMethod = false;
writeStreamHeader(); 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 ...@@ -172,10 +179,18 @@ public class ObjectOutputStream extends OutputStream
{ {
if (useSubclassMethod) if (useSubclassMethod)
{ {
if (dump)
dumpElementln ("WRITE OVERRIDE: " + obj);
writeObjectOverride(obj); writeObjectOverride(obj);
return; return;
} }
if (dump)
dumpElementln ("WRITE: " + obj);
depth += 2;
boolean was_serializing = isSerializing; boolean was_serializing = isSerializing;
boolean old_mode = setBlockDataMode(false); boolean old_mode = setBlockDataMode(false);
try try
...@@ -318,6 +333,8 @@ public class ObjectOutputStream extends OutputStream ...@@ -318,6 +333,8 @@ public class ObjectOutputStream extends OutputStream
if (obj instanceof Serializable) if (obj instanceof Serializable)
{ {
Object prevObject = this.currentObject;
ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
currentObject = obj; currentObject = obj;
ObjectStreamClass[] hierarchy = ObjectStreamClass[] hierarchy =
ObjectStreamClass.getObjectStreamClasses(clazz); ObjectStreamClass.getObjectStreamClasses(clazz);
...@@ -329,17 +346,25 @@ public class ObjectOutputStream extends OutputStream ...@@ -329,17 +346,25 @@ public class ObjectOutputStream extends OutputStream
fieldsAlreadyWritten = false; fieldsAlreadyWritten = false;
if (currentObjectStreamClass.hasWriteMethod()) if (currentObjectStreamClass.hasWriteMethod())
{ {
if (dump)
dumpElementln ("WRITE METHOD CALLED FOR: " + obj);
setBlockDataMode(true); setBlockDataMode(true);
callWriteMethod(obj, currentObjectStreamClass); callWriteMethod(obj, currentObjectStreamClass);
setBlockDataMode(false); setBlockDataMode(false);
realOutput.writeByte(TC_ENDBLOCKDATA); realOutput.writeByte(TC_ENDBLOCKDATA);
if (dump)
dumpElementln ("WRITE ENDBLOCKDATA FOR: " + obj);
} }
else else
{
if (dump)
dumpElementln ("WRITE FIELDS CALLED FOR: " + obj);
writeFields(obj, currentObjectStreamClass); writeFields(obj, currentObjectStreamClass);
} }
}
currentObject = null; this.currentObject = prevObject;
currentObjectStreamClass = null; this.currentObjectStreamClass = prevObjectStreamClass;
currentPutField = null; currentPutField = null;
break; break;
} }
...@@ -360,12 +385,22 @@ public class ObjectOutputStream extends OutputStream ...@@ -360,12 +385,22 @@ public class ObjectOutputStream extends OutputStream
setBlockDataMode(false); setBlockDataMode(false);
try try
{ {
if (Configuration.DEBUG)
{
e.printStackTrace(System.out);
}
writeObject(e); writeObject(e);
} }
catch (IOException ioe) catch (IOException ioe)
{ {
throw new StreamCorruptedException StreamCorruptedException ex =
("Exception " + ioe + " thrown while exception was being written to stream."); new StreamCorruptedException
(ioe + " thrown while exception was being written to stream.");
if (Configuration.DEBUG)
{
ex.printStackTrace(System.out);
}
throw ex;
} }
reset (true); reset (true);
...@@ -375,6 +410,10 @@ public class ObjectOutputStream extends OutputStream ...@@ -375,6 +410,10 @@ public class ObjectOutputStream extends OutputStream
{ {
isSerializing = was_serializing; isSerializing = was_serializing;
setBlockDataMode(old_mode); setBlockDataMode(old_mode);
depth -= 2;
if (dump)
dumpElementln ("END: " + obj);
} }
} }
...@@ -1171,6 +1210,9 @@ public class ObjectOutputStream extends OutputStream ...@@ -1171,6 +1210,9 @@ public class ObjectOutputStream extends OutputStream
field_name = fields[i].getName(); field_name = fields[i].getName();
type = fields[i].getType(); type = fields[i].getType();
if (dump)
dumpElementln ("WRITE FIELD: " + field_name + " type=" + type);
if (type == Boolean.TYPE) if (type == Boolean.TYPE)
realOutput.writeBoolean(getBooleanField(obj, osc.forClass(), field_name)); realOutput.writeBoolean(getBooleanField(obj, osc.forClass(), field_name));
else if (type == Byte.TYPE) else if (type == Byte.TYPE)
...@@ -1512,6 +1554,14 @@ public class ObjectOutputStream extends OutputStream ...@@ -1512,6 +1554,14 @@ public class ObjectOutputStream extends OutputStream
return m; 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 // this value comes from 1.2 spec, but is used in 1.1 as well
private final static int BUFFER_SIZE = 1024; private final static int BUFFER_SIZE = 1024;
...@@ -1534,6 +1584,12 @@ public class ObjectOutputStream extends OutputStream ...@@ -1534,6 +1584,12 @@ public class ObjectOutputStream extends OutputStream
private int protocolVersion; private int protocolVersion;
private boolean useSubclassMethod; 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 static
{ {
if (Configuration.INIT_LOAD_LIBRARY) if (Configuration.INIT_LOAD_LIBRARY)
......
...@@ -19,6 +19,8 @@ details. */ ...@@ -19,6 +19,8 @@ details. */
#include <java/lang/Class.h> #include <java/lang/Class.h>
#include <java/lang/reflect/Modifier.h> #include <java/lang/reflect/Modifier.h>
#include <java/lang/reflect/Method.h> #include <java/lang/reflect/Method.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/SecurityManager.h>
#ifdef DEBUG #ifdef DEBUG
#include <java/lang/System.h> #include <java/lang/System.h>
...@@ -69,3 +71,33 @@ java::io::ObjectInputStream::callConstructor (jclass klass, jobject obj) ...@@ -69,3 +71,33 @@ java::io::ObjectInputStream::callConstructor (jclass klass, jobject obj)
+ m->offset); + m->offset);
_Jv_CallAnyMethodA (obj, JvPrimClass (void), meth, false, arg_types, NULL); _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 ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment