mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 19:03:59 +08:00
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
This commit is contained in:
parent
aeec4861c4
commit
9125dc3292
@ -1,3 +1,11 @@
|
||||
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>
|
||||
|
||||
* m4/druntime/cpu.m4 (DRUNTIME_CPU_SOURCES): Quote brackets.
|
||||
|
@ -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
|
||||
|
@ -14,6 +14,8 @@
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib libphobos-dg.exp
|
||||
|
||||
# Initialize dg.
|
||||
dg-init
|
||||
|
||||
|
39
libphobos/testsuite/libphobos.thread/tlsgc_sections.d
Normal file
39
libphobos/testsuite/libphobos.thread/tlsgc_sections.d
Normal file
@ -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();
|
||||
}
|
Loading…
Reference in New Issue
Block a user