Why does this program cause an NPE in LibgcjInternalFinalizerThread ??
David Daney
ddaney@avtrex.com
Wed Aug 20 00:28:00 GMT 2003
Tom Tromey wrote:
>>>>>>"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;
>
This patch screws up find_slot(), because it stops if reference is NULL,
we don't want it to do this because the real entry may be further down
in the list and we need to skip the DELETED row.
>
>
More information about the Java
mailing list