Why does this program cause an NPE in LibgcjInternalFinalizerThread ??

Tom Tromey tromey@redhat.com
Wed Aug 20 00:11:00 GMT 2003


>>>>> "David" == David Daney <ddaney@avtrex.com> writes:

David> The object_list.reference is pointing to either a WeakReference or a
David> SoftReference. At some as yet unknown point it points something other
David> than one of these, causing a crash usually when ref->enqueue() is
David> called because the vtable of the object is not a Reference vtable.
I did find one problem in the logic. Suppose we completely finalized
some object (ran the finalizer and everything else). Then the slot in
the hash table would be marked with weight DELETED. However, the
reference field in this slot would never be overwritten.
See the appended patch. This doesn't seem to help, though. Your
program still hangs for me.
FWIW I would still tend to suspect this code rather than the GC.
One thing you could try is putting a breakpoint at the call to
ref->enqueue(). Then make this conditional on `ref' being wrong. For
instance, you could change your test program to only allocate
WeakReference objects, then test to see if the vtable for ref points
to the right place.
>From that you might be able to work backward to find out what is going
wrong. If the memory in question is being reallocated, then the
question is, why wasn't that particular slot in the hash table
cleared? The idea is that whenever a Reference or an object observed
by a Reference is collected, we wind up in the code in this file,
which then keeps the hash table in sync. To see the behavior you
posit, this must have gone wrong somewhere. Either we let the state
become inconsistent (see appended patch :-) or there is a GC bug, and
we aren't being notified of some important transition.
I wonder if calling Reference.clear can also cause problems here. In
this case, if the Reference is collected before its referent, it seems
like remove_from_hash will fail. Blah.
Also, FWIW, I don't think we call Reference.clear when we're supposed
to. Bugs abound :-(
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
	* java/lang/ref/natReference.cc (finalize_referred_to_object):
	Clear `reference' in list when removing dead object.
	(find_slot): Added an assert.
Index: java/lang/ref/natReference.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/ref/natReference.cc,v
retrieving revision 1.3
diff -u -r1.3 natReference.cc
--- java/lang/ref/natReference.cc 19 Nov 2002 21:59:41 -0000 1.3
+++ java/lang/ref/natReference.cc 19 Aug 2003 23:50:33 -0000
@@ -1,6 +1,6 @@
 // natReference.cc - Native code for References
 
-/* Copyright (C) 2001, 2002 Free Software Foundation
+/* Copyright (C) 2001, 2002, 2003 Free Software Foundation
 
 This file is part of libgcj.
 
@@ -89,7 +89,10 @@
 	 return &hash[deleted_index];
 	}
 else if (ptr->weight == DELETED)
-	deleted_index = index;
+	{
+	 deleted_index = index;
+	 JvAssert (ptr->reference == NULL);
+	}
 index = (index + step) & (hash_size - 1);
 JvAssert (index != start_index);
 }
@@ -217,6 +220,7 @@
 // run, all the object's references have been processed, and the
 // object is unreachable. There is, at long last, no way to
 // resurrect it.
+ list->reference = NULL;
 list->weight = DELETED;
 --hash_count;
 return;


More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /