From 3941b26033f10ba7f65828d600a8ac35dfa16dc9 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 27 Mar 2014 18:07:25 +0000 Subject: [PATCH] re PR libstdc++/60612 (Throwing exception, catching and rethrowing (std::exception_ptr) in destructor leads to segfault) PR libstdc++/60612 * libsupc++/eh_ptr.cc: Assert __cxa_dependent_exception layout is compatible with __cxa_exception. * libsupc++/unwind-cxx.h (__cxa_dependent_exception): Add padding. Fix typos in comments. * testsuite/18_support/exception_ptr/60612-terminate.cc: New. * testsuite/18_support/exception_ptr/60612-unexpected.cc: New. From-SVN: r208871 --- libstdc++-v3/ChangeLog | 10 +++++ libstdc++-v3/libsupc++/eh_ptr.cc | 26 ++++++++++++ libstdc++-v3/libsupc++/unwind-cxx.h | 9 +++- .../exception_ptr/60612-terminate.cc | 41 +++++++++++++++++++ .../exception_ptr/60612-unexpected.cc | 41 +++++++++++++++++++ 5 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 libstdc++-v3/testsuite/18_support/exception_ptr/60612-terminate.cc create mode 100644 libstdc++-v3/testsuite/18_support/exception_ptr/60612-unexpected.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index f6008d1e3e9..9a360993b06 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2014-03-27 Jonathan Wakely + + PR libstdc++/60612 + * libsupc++/eh_ptr.cc: Assert __cxa_dependent_exception layout is + compatible with __cxa_exception. + * libsupc++/unwind-cxx.h (__cxa_dependent_exception): Add padding. + Fix typos in comments. + * testsuite/18_support/exception_ptr/60612-terminate.cc: New. + * testsuite/18_support/exception_ptr/60612-unexpected.cc: New. + 2014-03-25 Jonathan Wakely PR libstdc++/60658 diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc index 6508749e56c..8c25a81ae4a 100644 --- a/libstdc++-v3/libsupc++/eh_ptr.cc +++ b/libstdc++-v3/libsupc++/eh_ptr.cc @@ -35,6 +35,32 @@ using namespace __cxxabiv1; +// Verify assumptions about member layout in exception types +namespace +{ +template + constexpr std::size_t unwindhdr() + { return offsetof(Ex, unwindHeader); } + +template + constexpr std::size_t termHandler() + { return unwindhdr() - offsetof(Ex, terminateHandler); } + +static_assert( termHandler<__cxa_exception>() + == termHandler<__cxa_dependent_exception>(), + "__cxa_dependent_exception::termHandler layout is correct" ); + +#ifndef __ARM_EABI_UNWINDER__ +template + constexpr std::ptrdiff_t adjptr() + { return unwindhdr() - offsetof(Ex, adjustedPtr); } + +static_assert( adjptr<__cxa_exception>() + == adjptr<__cxa_dependent_exception>(), + "__cxa_dependent_exception::adjustedPtr layout is correct" ); +#endif +} + std::__exception_ptr::exception_ptr::exception_ptr() _GLIBCXX_USE_NOEXCEPT : _M_exception_object(0) { } diff --git a/libstdc++-v3/libsupc++/unwind-cxx.h b/libstdc++-v3/libsupc++/unwind-cxx.h index a7df60380c0..f57c53637cf 100644 --- a/libstdc++-v3/libsupc++/unwind-cxx.h +++ b/libstdc++-v3/libsupc++/unwind-cxx.h @@ -81,7 +81,7 @@ struct __cxa_exception // Stack of exceptions in cleanups. __cxa_exception* nextPropagatingException; - // The nuber of active cleanup handlers for this exception. + // The number of active cleanup handlers for this exception. int propagationCount; #else // Cache parsed handler data from the personality routine Phase 1 @@ -114,6 +114,11 @@ struct __cxa_dependent_exception // The primary exception this thing depends on. void *primaryException; + // Unused member to get similar layout to __cxa_exception, otherwise the + // alignment requirements of _Unwind_Exception would require padding bytes + // before the unwindHeader member. + void (_GLIBCXX_CDTOR_CALLABI *__padding)(void *); + // The C++ standard has entertaining rules wrt calling set_terminate // and set_unexpected in the middle of the exception cleanup process. std::unexpected_handler unexpectedHandler; @@ -130,7 +135,7 @@ struct __cxa_dependent_exception // Stack of exceptions in cleanups. __cxa_exception* nextPropagatingException; - // The nuber of active cleanup handlers for this exception. + // The number of active cleanup handlers for this exception. int propagationCount; #else // Cache parsed handler data from the personality routine Phase 1 diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/60612-terminate.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/60612-terminate.cc new file mode 100644 index 00000000000..ec5940d6b21 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/exception_ptr/60612-terminate.cc @@ -0,0 +1,41 @@ +// { dg-options "-std=gnu++11" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// PR libstdc++/60612 + +#include +#include + +void terminate() { _Exit(0); } + +void f() noexcept +{ + try { + throw 1; + } catch (...) { + std::set_terminate(terminate); + std::rethrow_exception(std::current_exception()); + } +} + +int main() +{ + f(); +} diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/60612-unexpected.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/60612-unexpected.cc new file mode 100644 index 00000000000..3f7e2cf379d --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/exception_ptr/60612-unexpected.cc @@ -0,0 +1,41 @@ +// { dg-options "-std=gnu++11" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// PR libstdc++/60612 + +#include +#include + +void unexpected() { _Exit(0); } + +void f() throw() +{ + try { + throw 1; + } catch (...) { + std::set_unexpected(unexpected); + std::rethrow_exception(std::current_exception()); + } +} + +int main() +{ + f(); +}