From patchwork Thu Apr 25 15:59:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1090946 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-499670-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=gdcproject.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="UeImeBq+"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44qhhV5FLJz9s00 for ; Fri, 26 Apr 2019 01:59:33 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=T3Mi50yk05L3v4KmhsXKNlEqXasD5f7yn1cqVxs1NvPtcB lZHTv15JA+5Wo3ZTkMY/SSwe82xqBrwQtng929RhujivBLHdIEXa5HhBROoQ9jlp 9Pbc0lJ1BrHMLzBkweGsLSYqEd0iKT2vHwMngNdPopnKR5BAVcXAgomu+H5lc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=a0Ho+wT0chUgPrcV8FZSDxVWGx8=; b=UeImeBq+u9XbkGRSaSNG 9BfrNXpQqSKdJDUGRM0WDh+5rZ98LG/B/PWEUft9HvVXXGtiua1DO2X8hEgdTzjS bKmTawfSsj4aJ8juITCKVzAKqN8OdcsXaAUcT1esuTaljhh4vlDB/vTphcwMGBQo G22sCTyubXX+7xpbYWxiu+U= Received: (qmail 31952 invoked by alias); 25 Apr 2019 15:59:26 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 31944 invoked by uid 89); 25 Apr 2019 15:59:25 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mail-qk1-f181.google.com Received: from mail-qk1-f181.google.com (HELO mail-qk1-f181.google.com) (209.85.222.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 25 Apr 2019 15:59:24 +0000 Received: by mail-qk1-f181.google.com with SMTP id n68so67285qka.1 for ; Thu, 25 Apr 2019 08:59:24 -0700 (PDT) MIME-Version: 1.0 From: Iain Buclaw Date: Thu, 25 Apr 2019 17:59:11 +0200 Message-ID: Subject: [PATCH, PR d/90250] Committed fix segfault in runtime caused by unexpected GC of TLS data. To: gcc-patches X-IsSubscribed: yes Hi, Patch fixes a tlsgc bug on non-glibc targets. As explained in the bug report, glibc puts the TLS area for each new thread at the beginning of the newly created stack. Due to the way libdruntime detects the stack bottom, we end up marking all TLS data along with what we think is the stack. On other platforms, this is not the case, so memory referenced by thread-local data will get unexpectedly freed, making the use of threads and TLS unworkable. Regression tested on x86_64-linux-gnu and x86_64-freebsd. Committed to trunk as r270576. diff --git a/libphobos/libdruntime/gcc/sections/elf_shared.d b/libphobos/libdruntime/gcc/sections/elf_shared.d index 3a2c85cba64..1eafecdd322 100644 --- a/libphobos/libdruntime/gcc/sections/elf_shared.d +++ b/libphobos/libdruntime/gcc/sections/elf_shared.d @@ -308,7 +308,13 @@ else */ Array!(void[])* initTLSRanges() nothrow @nogc { - return &_tlsRanges(); + auto rngs = &_tlsRanges(); + if (rngs.empty) + { + foreach (ref pdso; _loadedDSOs) + rngs.insertBack(pdso.tlsRange()); + } + return rngs; } void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc diff --git a/libphobos/testsuite/libphobos.thread/thread.exp b/libphobos/testsuite/libphobos.thread/thread.exp index d35df567ab3..3e760d3e370 100644 --- a/libphobos/testsuite/libphobos.thread/thread.exp +++ b/libphobos/testsuite/libphobos.thread/thread.exp @@ -14,6 +14,8 @@ # along with GCC; see the file COPYING3. If not see # . +load_lib libphobos-dg.exp + # Initialize dg. dg-init diff --git a/libphobos/testsuite/libphobos.thread/tlsgc_sections.d b/libphobos/testsuite/libphobos.thread/tlsgc_sections.d new file mode 100644 index 00000000000..1421d926a38 --- /dev/null +++ b/libphobos/testsuite/libphobos.thread/tlsgc_sections.d @@ -0,0 +1,39 @@ +final class Class +{ + // This gets triggered although the instance always stays referenced. + ~this() + { + import core.stdc.stdlib; + abort(); + } +} + +Class obj; + +static this() +{ + obj = new Class; +} + +static ~this() +{ + // Free without destruction to avoid triggering abort() + import core.memory; + GC.free(cast(void*)obj); +} + +void doit() +{ + foreach (i; 0 .. 10_000) + new ubyte[](100_000); +} + +void main() +{ + import core.thread; + auto t = new Thread(&doit); + t.start(); + + // This triggers the GC that frees the still referenced Class instance. + doit(); +}