From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29154 invoked by alias); 16 Jul 2004 14:32:27 -0000 Mailing-List: contact libc-hacker-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sources.redhat.com Received: (qmail 29045 invoked from network); 16 Jul 2004 14:32:26 -0000 Received: from unknown (HELO sunsite.ms.mff.cuni.cz) (195.113.15.26) by sourceware.org with SMTP; 16 Jul 2004 14:32:26 -0000 Received: from sunsite.ms.mff.cuni.cz (sunsite.mff.cuni.cz [127.0.0.1]) by sunsite.ms.mff.cuni.cz (8.12.8/8.12.8) with ESMTP id i6GCGe3j005030; Fri, 16 Jul 2004 14:16:40 +0200 Received: (from jakub@localhost) by sunsite.ms.mff.cuni.cz (8.12.8/8.12.8/Submit) id i6GCGepG005015; Fri, 16 Jul 2004 14:16:40 +0200 Date: Fri, 16 Jul 2004 14:32:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers , Paolo Carlini , Ulrich.Weigand@de.ibm.com, libstdc++ Subject: [PATCH] Fix locking issue in newlocale Message-ID: <20040716121639.GJ30497@sunsite.ms.mff.cuni.cz> Reply-To: Jakub Jelinek References: <40F79EAB.1060107@suse.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <40F79EAB.1060107@suse.de> User-Agent: Mutt/1.4.1i X-SW-Source: 2004-07/txt/msg00034.txt.bz2 On Fri, Jul 16, 2004 at 11:23:55AM +0200, Paolo Carlini wrote: > > And in fact, in one crash I have analysed, it looks as if glibc-internal > > data structures are corrupted. Indeed, you're right. I have been able to reproduce this with on 4way x86-64: #define _GNU_SOURCE #include #include const char *locales[] = { "de_DE.ISO-8859-1", "en_US.ISO-8859-1" }; void * tf (void *arg) { int i; for (i = 0; i < 100000; ++i) { locale_t l = newlocale (LC_ALL_MASK, locales[i & 1], NULL); freelocale (l); } } void * tf2 (void *arg) { int i; for (i = 0; i < 100000; ++i) setlocale (LC_ALL, locales[(i % 27) & 1]); } int main (void) { pthread_t p[10]; int i; for (i = 0; i < 10; ++i) pthread_create (&p[i], NULL, i % 2 ? tf : tf2, NULL); for (i = 0; i < 10; ++i) pthread_join (p[i], NULL); return 0; } (not every time, but with while /tmp/test; do :; done it always crashed after a while). With the patch below it doesn't crash (at least for the 15 minutes I was running this test before stopping it). duplocale/freelocale already use this lock. 2004-07-16 Jakub Jelinek * locale/newlocale.c: Include bits/libc-lock.h. (__libc_setlocale_lock): Extern decl. (__newlocale): Use it. Reported by Ulrich Weigand . --- libc/locale/newlocale.c.jj 2004-07-16 09:33:23.000000000 -0400 +++ libc/locale/newlocale.c 2004-07-16 09:44:33.000000000 -0400 @@ -1,5 +1,6 @@ /* Return a reference to locale information record. - Copyright (C) 1996,1997,1999,2000,2001,2002 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2004 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -19,6 +20,7 @@ 02111-1307 USA. */ #include +#include #include #include #include @@ -27,6 +29,10 @@ #include "localeinfo.h" +/* Lock for protecting global data. */ +__libc_lock_define (extern , __libc_setlocale_lock attribute_hidden) + + /* Use this when we come along an error. */ #define ERROR_RETURN \ do { \ @@ -154,6 +160,9 @@ __newlocale (int category_mask, const ch ERROR_RETURN; } + /* Protect global data. */ + __libc_lock_lock (__libc_setlocale_lock); + /* Now process all categories we are interested in. */ names_len = 0; for (cnt = 0; cnt < __LC_LAST; ++cnt) @@ -171,6 +180,9 @@ __newlocale (int category_mask, const ch && result.__locales[cnt]->usage_count != UNDELETABLE) /* We can remove the data. */ _nl_remove_locale (cnt, result.__locales[cnt]); + + /* Critical section left. */ + __libc_lock_unlock (__libc_setlocale_lock); return NULL; } @@ -249,6 +261,9 @@ __newlocale (int category_mask, const ch free (base); } + /* Critical section left. */ + __libc_lock_unlock (__libc_setlocale_lock); + /* Update the special members. */ update: { Jakub