This adds a new function to libsupc++ which will free the memory still in use by the pool used for allocating exceptions when malloc fails.
This is similar to glibc's __libc_freeres, which valgrind (and other tools?) use to tell glibc to deallocate everything before exiting. I initially called it __gnu_cxx::__free_eh_pool() but I figured we might have other memory in use at some later date, and we wouldn't want valgrind to have to start calling a second function, nor make a function called __free_eh_pool() actually free other things. I intentionally *didn't* lock the pool's mutex before freeing it, because this should never be called in a context where multiple threads are still active and accessing the pool. Thoughts? Is the new test a good idea, or will exposing it like that in the testsuite just give users the idea that they can/should be doing the same themselves? [ Aside: should the actual pool be created with placement-new to [ ensure it doesn't ever get destroyed? [ [ alignas(pool) unsigned char poolbuf[sizeof(pool)]; [ pool& emergency_pool = *::new(poolbuf) pool;
commit 40fed1db72b0a4852d5890c2c464a0baabb02b74 Author: Jonathan Wakely <jwak...@redhat.com> Date: Wed Feb 24 18:22:30 2016 +0000 libstdc++/69945 Add __gnu_cxx::__freeres hook * config/abi/pre/gnu.ver: Add new symbol. * libsupc++/eh_alloc.cc (__gnu_cxx::__freeres): Define. * testsuite/18_support/free_eh_pool.cc: New test. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 41069d1..5c6b0fe 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -2148,6 +2148,8 @@ CXXABI_1.3.10 { _ZGTtNKSt13bad_exceptionD1Ev; _ZGTtNKSt13bad_exception4whatEv; + _ZN9__gnu_cxx9__freeresEv; + } CXXABI_1.3.9; # Symbols in the support library (libsupc++) supporting transactional memory. diff --git a/libstdc++-v3/libsupc++/eh_alloc.cc b/libstdc++-v3/libsupc++/eh_alloc.cc index 6973af3..d362e40 100644 --- a/libstdc++-v3/libsupc++/eh_alloc.cc +++ b/libstdc++-v3/libsupc++/eh_alloc.cc @@ -73,6 +73,10 @@ using namespace __cxxabiv1; # define EMERGENCY_OBJ_COUNT 4 #endif +namespace __gnu_cxx +{ + void __freeres(); +} namespace { @@ -106,6 +110,8 @@ namespace // to implement in_pool. char *arena; std::size_t arena_size; + + friend void __gnu_cxx::__freeres(); }; pool::pool() @@ -244,6 +250,19 @@ namespace pool emergency_pool; } +namespace __gnu_cxx +{ + void + __freeres() + { + if (emergency_pool.arena) + { + ::free(emergency_pool.arena); + emergency_pool.arena = 0; + } + } +} + extern "C" void * __cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) _GLIBCXX_NOTHROW { diff --git a/libstdc++-v3/testsuite/18_support/free_eh_pool.cc b/libstdc++-v3/testsuite/18_support/free_eh_pool.cc new file mode 100644 index 0000000..9712d3d --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/free_eh_pool.cc @@ -0,0 +1,35 @@ +// Copyright (C) 2016 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/>. + +// { dg-do run } + +namespace __gnu_cxx { + void __freeres(); +} + +struct X { + ~X() { + __gnu_cxx::__freeres(); + } +}; + +X x; + +int +main() +{ +}