Commit 9125dc32 by Iain Buclaw Committed by Iain Buclaw

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.

From-SVN: r270576
parent aeec4861
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.
2019-04-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2019-04-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* m4/druntime/cpu.m4 (DRUNTIME_CPU_SOURCES): Quote brackets. * m4/druntime/cpu.m4 (DRUNTIME_CPU_SOURCES): Quote brackets.
......
...@@ -308,7 +308,13 @@ else ...@@ -308,7 +308,13 @@ else
*/ */
Array!(void[])* initTLSRanges() nothrow @nogc 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 void finiTLSRanges(Array!(void[])* rngs) nothrow @nogc
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
# along with GCC; see the file COPYING3. If not see # along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>. # <http://www.gnu.org/licenses/>.
load_lib libphobos-dg.exp
# Initialize dg. # Initialize dg.
dg-init dg-init
......
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();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment