Index: libcxxabi/trunk/src/cxa_exception_storage.cpp =================================================================== --- libcxxabi/trunk/src/cxa_exception_storage.cpp +++ libcxxabi/trunk/src/cxa_exception_storage.cpp @@ -46,6 +46,7 @@ #include #include // for calloc, free +#include // for memset #include "abort_message.h" // In general, we treat all pthread errors as fatal. @@ -53,12 +54,30 @@ // call __cxa_get_globals() and cause infinite recursion. namespace __cxxabiv1 { + +#include "fallback_malloc.ipp" + +// Allocate some memory from _somewhere_ +static void *do_calloc(size_t count, size_t size) { + void *ptr = std::calloc(count, size); + if (NULL == ptr) { // if calloc fails, fall back to emergency stash + ptr = fallback_malloc(size * count); + if (NULL != ptr) + std::memset(ptr, 0, size * count); + } + return ptr; +} + +static void do_free(void *ptr) { + is_fallback_ptr(ptr) ? fallback_free(ptr) : std::free(ptr); +} + namespace { pthread_key_t key_; pthread_once_t flag_ = PTHREAD_ONCE_INIT; void destruct_ (void *p) { - std::free ( p ); + do_free ( p ); if ( 0 != ::pthread_setspecific ( key_, NULL ) ) abort_message("cannot zero out thread value for __cxa_get_globals()"); } @@ -77,7 +96,7 @@ // If this is the first time we've been asked for these globals, create them if ( NULL == retVal ) { retVal = static_cast<__cxa_eh_globals*> - (std::calloc (1, sizeof (__cxa_eh_globals))); + (do_calloc (1, sizeof (__cxa_eh_globals))); if ( NULL == retVal ) abort_message("cannot allocate __cxa_eh_globals"); if ( 0 != pthread_setspecific ( key_, retVal ) ) Index: libcxxabi/trunk/test/test_exception_storage_nodynmem.pass.cpp =================================================================== --- /dev/null +++ libcxxabi/trunk/test/test_exception_storage_nodynmem.pass.cpp @@ -0,0 +1,21 @@ +//===--------------- test_exception_storage_nodynmem.cpp ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include + +// Override calloc to simulate exhaustion of dynamic memory +void *calloc(size_t, size_t) { return 0; } + +int main(int argc, char *argv[]) { + try { + throw 42; + } catch (...) { + } + return 0; +}