This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] PR libstdc++/59392: Fix ARM EABI uncaught throw from unexpected exception handler
- From: Roland McGrath <mcgrathr at google dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Cc: Mark Seaborn <mseaborn at google dot com>
- Date: Wed, 12 Mar 2014 15:46:04 -0700
- Subject: Re: [PATCH] PR libstdc++/59392: Fix ARM EABI uncaught throw from unexpected exception handler
- Authentication-results: sourceware.org; auth=none
- References: <CAB=4xhqXcMgpObWY6k2eAeY1D=nfWneni5pyY9wOEsWkdcMO5w at mail dot gmail dot com>
Committed (r208519 on trunk and r208520 on 4.8) after approval posted
in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59392.
Only the dates are changed from what I posted originally.
Thanks,
Roland
On Fri, Dec 6, 2013 at 3:24 PM, Roland McGrath <mcgrathr@google.com> wrote:
> [This patch is on the git-only branch roland/pr59392.]
>
> As described in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59392, this
> bug looks to have been present since 4.2 originally introduced support
> for ARM EABI-based C++ exception handling. I'd like to put this fix on
> trunk and 4.8, and don't personally care about older versions but the
> same fix should apply to all versions still being maintained.
>
> The nature of the bug is quite straightforward: it's an unconditional
> null pointer dereference in the code path for an unexpected throw done
> inside a user-supplied handler for unexpected exceptions. I'm not
> really sure if there are other ways to make it manifest.
>
> Mark Seaborn is responsible for identifying the fix, which mimics the
> similar code for the non-EABI implementation (and copies its comment).
> I filled it out with a regression test. (We're both covered by Google's
> blanket copyright assignment.)
>
> No regressions in 'make check-c++' on arm-linux-gnueabihf.
>
> Ok for trunk and 4.8?
>
>
> Thanks,
> Roland
>
>
> libstdc++-v3/
> 2013-12-06 Roland McGrath <mcgrathr@google.com>
> Mark Seaborn <mseaborn@google.com>
>
> PR libstdc++/59392
> * libsupc++/eh_call.cc (__cxa_call_unexpected): Call __do_catch with
> the address of a null pointer, not with a null pointer to pointer.
> Copy comment for this case from eh_personality.cc:__cxa_call_unexpected.
> * testsuite/18_support/bad_exception/59392.cc: New file.
>
> --- a/libstdc++-v3/libsupc++/eh_call.cc
> +++ b/libstdc++-v3/libsupc++/eh_call.cc
> @@ -140,7 +140,11 @@ __cxa_call_unexpected(void* exc_obj_in)
> &new_ptr) != ctm_failed)
> __throw_exception_again;
>
> - if (catch_type->__do_catch(&bad_exc, 0, 1))
> + // If the exception spec allows std::bad_exception, throw that.
> + // We don't have a thrown object to compare against, but since
> + // bad_exception doesn't have virtual bases, that's OK; just pass NULL.
> + void* obj = NULL;
> + if (catch_type->__do_catch(&bad_exc, &obj, 1))
> bad_exception_allowed = true;
> }
>
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/18_support/bad_exception/59392.cc
> @@ -0,0 +1,51 @@
> +// Copyright (C) 2013 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
> +// <http://www.gnu.org/licenses/>.
> +
> +#include <exception>
> +#include <cstdlib>
> +
> +class expected {};
> +class unexpected {};
> +class from_handler {};
> +
> +static void func_with_exception_spec() throw(expected)
> +{
> + throw unexpected();
> +}
> +
> +static void unexpected_handler()
> +{
> + throw from_handler();
> +}
> +
> +static void terminate_handler()
> +{
> + exit(0);
> +}
> +
> +// libstdc++/59392
> +int main()
> +{
> + std::set_unexpected(unexpected_handler);
> + std::set_terminate(terminate_handler);
> + try {
> + func_with_exception_spec();
> + } catch (expected&) {
> + abort();
> + }
> + abort();
> +}