From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2083 invoked by alias); 26 Sep 2008 15:58:21 -0000 Received: (qmail 2055 invoked by uid 48); 26 Sep 2008 15:58:21 -0000 Date: Fri, 26 Sep 2008 15:58:00 -0000 Message-ID: <20080926155821.2054.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug libgcj/18266] GCJ: Using references drops finalizers causing all apps to eventually crash ( SIGSEGV in GC_register_finalizer_inner () ) In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: java-prs@gcc.gnu.org From: "daney at gcc dot gnu dot org" Mailing-List: contact java-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: java-prs-owner@gcc.gnu.org X-SW-Source: 2008-q3/txt/msg00072.txt.bz2 ------- Comment #20 from daney at gcc dot gnu dot org 2008-09-26 15:58 ------- 1) Create an object. 2) Enter a synchronized block on the object and do Object.wait(). 3) In a second thread, enter a synchronized block on the object. There is lock contention, heavy lock escalation is guaranteed. Hash synchronization code registers a finalizer recording the old finalizer. The old finalizer is null as no finzlizers have been registered for the object. 4) Create a WeakReference to the Object. This adds a finalizer, overwriting and thus losing the Hash synchronization's finalizer. 5) Both threads leave the synchronized block. At this point the heavy_lock object in the hash synchronization code in no longer in use and is eligible for clean up. 6) Many other locks are acquired and released, some of these hash to the same value as the lock used in steps 1 and 2. Eventually the hash row for these locks is cleaned up. The clean up code restores the saved finalizer from step 3 which was null, thus overwriting the WeakReference's finalizer. 7) WeakReference's referent is GCed, but its finalizer has been removed in step 6, so it does not get cleaned up. If you ever synchronize o the If the object itself is a WeakReference, the same thing happens, but ref->enqueue is called on the WeakReference. If A different type of object has been allocated in the WeakReference's previous location, when the referent is finalized ref->enqueue will be called through the vtable of the new object resulting sometimes in SIGSEGV or other types of bad behavior. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18266