]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
nptl: Add PTHREAD_MIN_STACK C++ throw test [BZ #22636]
authorFlorian Weimer <fweimer@redhat.com>
Mon, 15 Jan 2018 14:30:00 +0000 (15:30 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Mon, 15 Jan 2018 14:30:00 +0000 (15:30 +0100)
ChangeLog
nptl/Makefile
nptl/tst-minstack-throw.cc [new file with mode: 0644]

index bbbdb2c80767562a41106b8cef97bab1e9706bb4..c2a4a41f6242fed8bbb935378f6b53f1bb51fc7d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-01-15  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ #22636]
+       * nptl/tst-minstack-throw.cc: New file.
+       * nptl/Makefile (tests): Add tst-minstack-throw.
+       (LDLIBS-tst-minstack-throw): Link with libstdc++.
+       [!CXX] (tests-unsupported): Add tst-minstack-throw.
+
 2018-01-15  Joseph Myers  <joseph@codesourcery.com>
 
        * scripts/build-many-glibcs.py (Context.checkout): Default
index 12c69f99d87add8466668ced271c3ea14670989c..d59caa5980d04ce7a5ceb7deefc625dbad9f23e1 100644 (file)
@@ -231,6 +231,7 @@ CFLAGS-tst-thread_local1.o = -std=gnu++11
 LDLIBS-tst-thread_local1 = -lstdc++
 CFLAGS-tst-thread-exit-clobber.o = -std=gnu++11
 LDLIBS-tst-thread-exit-clobber = -lstdc++
+LDLIBS-tst-minstack-throw = -lstdc++
 
 tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
        tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
@@ -307,7 +308,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
        tst-bad-schedattr \
        tst-thread_local1 tst-mutex-errorcheck tst-robust10 \
        tst-robust-fork tst-create-detached tst-memstream \
-       tst-thread-exit-clobber tst-minstack-cancel tst-minstack-exit
+       tst-thread-exit-clobber tst-minstack-cancel tst-minstack-exit \
+       tst-minstack-throw
 
 tests-internal := tst-rwlock19 tst-rwlock20 \
                  tst-sem11 tst-sem12 tst-sem13 \
@@ -457,7 +459,8 @@ endif
 
 ifeq (,$(CXX))
 # These tests require a C++ compiler and runtime.
-tests-unsupported += tst-cancel24 tst-cancel24-static tst-once5
+tests-unsupported += tst-cancel24 tst-cancel24-static tst-once5 \
+  tst-minstack-throw
 endif
 # These tests require a C++ compiler and runtime with thread_local support.
 ifneq ($(have-cxx-thread_local),yes)
diff --git a/nptl/tst-minstack-throw.cc b/nptl/tst-minstack-throw.cc
new file mode 100644 (file)
index 0000000..b0a897b
--- /dev/null
@@ -0,0 +1,87 @@
+/* Test that throwing C++ exceptions works with the minimum stack size.
+   Copyright (C) 2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdexcept>
+
+#include <limits.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/xthread.h>
+
+/* Throw a std::runtime_exception.  */
+__attribute__ ((noinline, noclone, weak))
+void
+do_throw_exception ()
+{
+  throw std::runtime_error ("test exception");
+}
+
+/* Class with a destructor, to trigger unwind handling.  */
+struct class_with_destructor
+{
+  class_with_destructor ();
+  ~class_with_destructor ();
+};
+
+__attribute__ ((noinline, noclone, weak))
+class_with_destructor::class_with_destructor ()
+{
+}
+
+__attribute__ ((noinline, noclone, weak))
+class_with_destructor::~class_with_destructor ()
+{
+}
+
+__attribute__ ((noinline, noclone, weak))
+void
+function_with_destructed_object ()
+{
+  class_with_destructor obj;
+  do_throw_exception ();
+}
+
+static void *
+threadfunc (void *closure)
+{
+  try
+    {
+      function_with_destructed_object ();
+      FAIL_EXIT1 ("no exception thrown");
+    }
+  catch (std::exception &e)
+    {
+      TEST_COMPARE (strcmp (e.what (), "test exception"), 0);
+      return reinterpret_cast<void *> (threadfunc);
+    }
+  FAIL_EXIT1 ("no exception caught");
+}
+
+static int
+do_test (void)
+{
+  pthread_attr_t attr;
+  xpthread_attr_init (&attr);
+  xpthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+  pthread_t thr = xpthread_create (&attr, threadfunc, NULL);
+  TEST_VERIFY (xpthread_join (thr) == threadfunc);
+  xpthread_attr_destroy (&attr);
+  return 0;
+}
+
+#include <support/test-driver.c>