Bug 90250 - libphobos: segfault in runtime caused by unexpected GC of TLS data.
Summary: libphobos: segfault in runtime caused by unexpected GC of TLS data.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: d (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: ---
Assignee: Iain Buclaw
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-04-25 13:29 UTC by Iain Buclaw
Modified: 2019-04-25 15:32 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Iain Buclaw 2019-04-25 13:29:14 UTC
The crash is only observed on non Linux/glibc systems.

Reason being because glibc puts the TLS area for each new thread at the beginning of the newly created stack. Due to the way we detect the stack bottom, we hoover up the TLS data along with what we think the stack is.

This is of course a dirty implementation detail, but explains why things don't crash on GNU/Linux the way they are.

---
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();
}
Comment 1 Iain Buclaw 2019-04-25 15:32:10 UTC
Author: ibuclaw
Date: Thu Apr 25 15:31:35 2019
New Revision: 270576

URL: https://gcc.gnu.org/viewcvs?rev=270576&root=gcc&view=rev
Log:
libphobos: Fix segfault in runtime caused by unexpected GC of TLS data.

libphobos/ChangeLog:

2019-04-25  Iain Buclaw  <ibuclaw@gdcproject.org>

	PR d/90250
	* libdruntime/gcc/sections/elf_shared.d (initTLSRanges): Populate
	_tlsRanges in every startup thread.
	* testsuite/libphobos.thread/thread.exp: Load libphobos-dg.exp.
	* testsuite/libphobos.thread/tlsgc_sections.d: New test.

Added:
    trunk/libphobos/testsuite/libphobos.thread/tlsgc_sections.d
Modified:
    trunk/libphobos/ChangeLog
    trunk/libphobos/libdruntime/gcc/sections/elf_shared.d
    trunk/libphobos/testsuite/libphobos.thread/thread.exp
Comment 2 Iain Buclaw 2019-04-25 15:32:40 UTC
Done in r270576.