From patchwork Wed Mar 12 14:05:33 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vineet Gupta X-Patchwork-Id: 329470 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from silver.osuosl.org (silver.osuosl.org [140.211.166.136]) by ozlabs.org (Postfix) with ESMTP id 120B32C00E4 for ; Thu, 13 Mar 2014 01:06:03 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id 4190132FC0; Wed, 12 Mar 2014 14:06:01 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id b8Zg98WgtKji; Wed, 12 Mar 2014 14:05:57 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by silver.osuosl.org (Postfix) with ESMTP id 73D7E33101; Wed, 12 Mar 2014 14:05:57 +0000 (UTC) X-Original-To: uclibc@lists.busybox.net Delivered-To: uclibc@osuosl.org Received: from fraxinus.osuosl.org (fraxinus.osuosl.org [140.211.166.137]) by ash.osuosl.org (Postfix) with ESMTP id 612191CE6A9 for ; Wed, 12 Mar 2014 14:05:56 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 5DF178BEED for ; Wed, 12 Mar 2014 14:05:56 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EwV6C0JK8EiH for ; Wed, 12 Mar 2014 14:05:54 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from smtprelay.synopsys.com (smtprelay2.synopsys.com [198.182.60.111]) by fraxinus.osuosl.org (Postfix) with ESMTPS id 26A5B8BF98 for ; Wed, 12 Mar 2014 14:05:54 +0000 (UTC) Received: from us02secmta2.synopsys.com (us02secmta2.synopsys.com [10.12.235.98]) by smtprelay.synopsys.com (Postfix) with ESMTP id 586EA10C07A4; Wed, 12 Mar 2014 07:05:53 -0700 (PDT) Received: from us02secmta2.internal.synopsys.com (us02secmta2.internal.synopsys.com [127.0.0.1]) by us02secmta2.internal.synopsys.com (Service) with ESMTP id 4BFBE55F15; Wed, 12 Mar 2014 07:05:53 -0700 (PDT) Received: from mailhost.synopsys.com (mailhost1.synopsys.com [10.12.238.239]) by us02secmta2.internal.synopsys.com (Service) with ESMTP id D28EC55F02; Wed, 12 Mar 2014 07:05:52 -0700 (PDT) Received: from mailhost.synopsys.com (localhost [127.0.0.1]) by mailhost.synopsys.com (Postfix) with ESMTP id C254921C; Wed, 12 Mar 2014 07:05:52 -0700 (PDT) Received: from US01WEHTC2.internal.synopsys.com (us01wehtc2-vip.internal.synopsys.com [10.12.239.238]) by mailhost.synopsys.com (Postfix) with ESMTP id B081E21B; Wed, 12 Mar 2014 07:05:52 -0700 (PDT) Received: from IN01WEHTCB.internal.synopsys.com (10.144.199.105) by US01WEHTC2.internal.synopsys.com (10.12.239.237) with Microsoft SMTP Server (TLS) id 14.3.158.1; Wed, 12 Mar 2014 07:05:52 -0700 Received: from vg-E6520.internal.synopsys.com (10.12.197.50) by IN01WEHTCB.internal.synopsys.com (10.144.199.243) with Microsoft SMTP Server (TLS) id 14.3.158.1; Wed, 12 Mar 2014 19:35:48 +0530 From: Vineet Gupta To: Subject: [PATCH] LT.old: Make errno_location thread safe Date: Wed, 12 Mar 2014 19:35:33 +0530 Message-ID: <1394633133-15657-1-git-send-email-vgupta@synopsys.com> X-Mailer: git-send-email 1.8.3.2 MIME-Version: 1.0 X-Originating-IP: [10.12.197.50] Cc: Joern Rennecke , Jeremy Bennett , Vineet Gupta , Christian Ruppert , Francois Bedard X-BeenThere: uclibc@uclibc.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Discussion and development of uClibc \(the embedded C library\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: uclibc-bounces@uclibc.org Sender: uclibc-bounces@uclibc.org [summary: Get rid of libc alias __GI___errno_location] It seems with Linuxthreads.old (yet to confirm NPTL) errno is not thread safe. A simple pthread linked test program (at the bottom) which makes a failing syscall e.g. open("/not-exist") fails to observe the right errno in the thread (main is OK) Conceptually uClibc defines weak __errno_location() while libpthread defines astrong variant. This arrangement shd work when using -pthread links. The spoil sport is __GI___errno_location, intended to bypass PLT for intra-libc callers. It gets called even in case of LT.old links given the syscall wrappers in libpthread (LT.old). e.g. open [ in libpthread ] pthreadsetcanceltype() __libc_open() __GI__open() ... - __GI___errno_location [ existing ] + __errno_location [ intended ] .... pthreadsetcanceltype() So the solution is to get rid of GI alias for errno_location altogether. I tested this on master for ARC as well as an ARMv7 buildroot LT.old build (daily snapshot of uClibc) and fix works on both. -------- before ------->8---------- [Main thread] Initial errno = 99 errno @b6f6c338 = 2 (OK) [Child Thread] Initial errno = 0 errno @be1ffee8 = 0 (BROKEN) Errno in main after child 4 ------- after ----->8------------------ [Main thread] Initial errno = 99 errno @b6f9a338 = 2 (OK) [Child Thread] Initial errno = 0 errno @be1ffee8 = 2 (OK) Errno in main after child 4 ============Test case =================== /* $CROSS-gcc -o errno-arc -lpthread */ void *th(void *str) { int fd; printf("\n[%s] Initial errno = %d\n", (char *)str, errno); fd = open("/nothing", O_RDONLY); if (fd >= 0) { close(fd); //printf("success\n"); } else printf("errno @%x = %d (%s)\n", &errno, errno, errno ? "OK" : "BROKEN"); errno = 66; return NULL; } int main(void) { pthread_t t; void *r; int err; errno = 99; th("Main thread"); err = pthread_create(&t, NULL, th, "Child Thread"); if (err) { fprintf(stderr, "could not spawn thread: %s\n", strerror(err)); return 1; } pthread_join(t, &r); printf("Errno in main after child %d\n", errno); return 0; } Cc: Christian Ruppert CC: Francois Bedard Cc: Joern Rennecke Cc: Jeremy Bennett Signed-off-by: Vineet Gupta --- libc/misc/internals/__errno_location.c | 1 - libc/sysdeps/linux/common/bits/errno.h | 3 --- 2 files changed, 4 deletions(-) diff --git a/libc/misc/internals/__errno_location.c b/libc/misc/internals/__errno_location.c index be7a9093efa3..9bbc2d779653 100644 --- a/libc/misc/internals/__errno_location.c +++ b/libc/misc/internals/__errno_location.c @@ -16,4 +16,3 @@ int *__errno_location(void) { return &errno; } -libc_hidden_weak(__errno_location) diff --git a/libc/sysdeps/linux/common/bits/errno.h b/libc/sysdeps/linux/common/bits/errno.h index 777338fb1e0a..611b8359001a 100644 --- a/libc/sysdeps/linux/common/bits/errno.h +++ b/libc/sysdeps/linux/common/bits/errno.h @@ -43,11 +43,8 @@ /* Function to get address of global `errno' variable. */ extern int *__errno_location (void) __THROW __attribute__ ((__const__)); # ifdef _LIBC -# if !defined(__UCLIBC_HAS_TLS__) && !defined(__UCLIBC_HAS_THREADS__) extern int weak_const_function *__errno_location(void); -# endif # endif -libc_hidden_proto(__errno_location) # ifdef __UCLIBC_HAS_THREADS__ /* When using threads, errno is a per-thread value. */