Why does this program cause an NPE in LibgcjInternalFinalizerThread ??

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


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

David> This patch screws up find_slot(), because it stops if reference is
David> NULL, we don't want it to do this because the real entry may be
David> further down in the list and we need to skip the DELETED row.
So it does.
David> I think it would work if you set next=NULL, instead of reference.
I don't think so, because add_to_hash won't reset item->reference in
this case.
Here's another try. This one also doesn't fix the problem you're
seeing :-(
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
	* java/lang/ref/natReference.cc (finalize_referred_to_object):
	Set `list->reference' to DELETED_REFERENCE when removing dead
	object.
	(find_slot): Added an assert.
	(DELETED_REFERENCE): New define.
	(add_to_hash): Check for DELETED_REFERENCE.
	(remove_from_hash): Just return if found slot isn't ours.
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 20 Aug 2003 14:51:06 -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.
 
@@ -67,6 +67,8 @@
 // Number of slots total in HASH. Must be power of 2.
 static int hash_size = 0;
 
+#define DELETED_REFERENCE ((jobject) -1)
+
 static object_list *
 find_slot (jobject key)
 {
@@ -89,7 +91,10 @@
 	 return &hash[deleted_index];
 	}
 else if (ptr->weight == DELETED)
-	deleted_index = index;
+	{
+	 deleted_index = index;
+	 JvAssert (ptr->reference == DELETED_REFERENCE);
+	}
 index = (index + step) & (hash_size - 1);
 JvAssert (index != start_index);
 }
@@ -132,6 +137,11 @@
 java::lang::ref::Reference *ref
 = reinterpret_cast<java::lang::ref::Reference *> (obj);
 object_list *head = find_slot (ref->copy);
+
+ // We might have found a new slot. We can just ignore that here.
+ if (head->reference != ref->copy)
+ return;
+
 object_list **link = &head->next;
 head = head->next;
 
@@ -168,7 +178,7 @@
 // Use `copy' here because the `referent' field has been cleared.
 jobject referent = the_reference->copy;
 object_list *item = find_slot (referent);
- if (item->reference == NULL)
+ if (item->reference == NULL || item->reference == DELETED_REFERENCE)
 {
 // New item, so make an entry for the finalizer.
 item->reference = referent;
@@ -217,6 +227,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 = DELETED_REFERENCE;
 list->weight = DELETED;
 --hash_count;
 return;


More information about the Java mailing list

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