summaryrefslogtreecommitdiff
path: root/libphobos
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2019-04-25 15:31:35 +0000
committerIain Buclaw <ibuclaw@gcc.gnu.org>2019-04-25 15:31:35 +0000
commit9125dc3292822c748b1d866ea2d78e00708d5df6 (patch)
tree3168084ac2a7b9b2987f6195e7252b929f3123c6 /libphobos
parentaeec4861c41eb5afa5b0700103e6cc404047cc6d (diff)
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
Diffstat (limited to 'libphobos')
-rw-r--r--libphobos/ChangeLog8
-rw-r--r--libphobos/libdruntime/gcc/sections/elf_shared.d8
-rw-r--r--libphobos/testsuite/libphobos.thread/thread.exp2
-rw-r--r--libphobos/testsuite/libphobos.thread/tlsgc_sections.d39
4 files changed, 56 insertions, 1 deletions
diff --git a/libphobos/ChangeLog b/libphobos/ChangeLog
index f1b76bb88d2..0d937e02bfc 100644
--- a/libphobos/ChangeLog
+++ b/libphobos/ChangeLog
@@ -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.
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
# <http://www.gnu.org/licenses/>.
+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();
+}