summaryrefslogtreecommitdiff
path: root/src/cxa_exception.cpp
diff options
context:
space:
mode:
authorIgor Kudrin <ikudrin.dev@gmail.com>2016-10-07 08:48:28 +0000
committerIgor Kudrin <ikudrin.dev@gmail.com>2016-10-07 08:48:28 +0000
commitace657208972b9d29bff7e062a19f59199133a4d (patch)
tree67abd4c8253423b554220f454c8b7ac327dbbcdd /src/cxa_exception.cpp
parent8d4d9af454a985d8c10ffdb0c56e87efec25ddff (diff)
Recommit r282692: [libc++abi] Use fallback_malloc to allocate __cxa_eh_globals in case of dynamic memory exhaustion.
Throwing an exception for the first time may lead to call calloc to allocate memory for __cxa_eh_globals. If the memory pool is exhausted at that moment, it results in abnormal termination of the program. This patch addresses the issue by using fallback_malloc in that case. In this revision, some restrictions were added into the test to not run it in unsuitable environments. Differential Revision: https://reviews.llvm.org/D17815 git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@283531 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'src/cxa_exception.cpp')
-rw-r--r--src/cxa_exception.cpp28
1 files changed, 6 insertions, 22 deletions
diff --git a/src/cxa_exception.cpp b/src/cxa_exception.cpp
index 603f869..757b3d4 100644
--- a/src/cxa_exception.cpp
+++ b/src/cxa_exception.cpp
@@ -15,13 +15,10 @@
#include "cxxabi.h"
#include <exception> // for std::terminate
-#include <cstdlib> // for malloc, free
#include <cstring> // for memset
-#ifndef _LIBCXXABI_HAS_NO_THREADS
-# include <pthread.h> // for fallback_malloc.ipp's mutexes
-#endif
#include "cxa_exception.hpp"
#include "cxa_handlers.hpp"
+#include "fallback_malloc.h"
// +---------------------------+-----------------------------+---------------+
// | __cxa_exception | _Unwind_Exception CLNGC++\0 | thrown object |
@@ -104,20 +101,6 @@ static inline int decrementHandlerCount(__cxa_exception *exception) {
return --exception->handlerCount;
}
-#include "fallback_malloc.ipp"
-
-// Allocate some memory from _somewhere_
-static void *do_malloc(size_t size) {
- void *ptr = std::malloc(size);
- if (NULL == ptr) // if malloc fails, fall back to emergency stash
- ptr = fallback_malloc(size);
- return ptr;
-}
-
-static void do_free(void *ptr) {
- is_fallback_ptr(ptr) ? fallback_free(ptr) : std::free(ptr);
-}
-
/*
If reason isn't _URC_FOREIGN_EXCEPTION_CAUGHT, then the terminateHandler
stored in exc is called. Otherwise the exceptionDestructor stored in
@@ -158,7 +141,8 @@ extern "C" {
// user's exception object.
_LIBCXXABI_FUNC_VIS void *__cxa_allocate_exception(size_t thrown_size) throw() {
size_t actual_size = cxa_exception_size_from_exception_thrown_size(thrown_size);
- __cxa_exception* exception_header = static_cast<__cxa_exception*>(do_malloc(actual_size));
+ __cxa_exception *exception_header =
+ static_cast<__cxa_exception *>(__malloc_with_fallback(actual_size));
if (NULL == exception_header)
std::terminate();
std::memset(exception_header, 0, actual_size);
@@ -168,7 +152,7 @@ _LIBCXXABI_FUNC_VIS void *__cxa_allocate_exception(size_t thrown_size) throw() {
// Free a __cxa_exception object allocated with __cxa_allocate_exception.
_LIBCXXABI_FUNC_VIS void __cxa_free_exception(void *thrown_object) throw() {
- do_free(cxa_exception_from_thrown_object(thrown_object));
+ __free_with_fallback(cxa_exception_from_thrown_object(thrown_object));
}
@@ -177,7 +161,7 @@ _LIBCXXABI_FUNC_VIS void __cxa_free_exception(void *thrown_object) throw() {
// Otherwise, it will work like __cxa_allocate_exception.
void * __cxa_allocate_dependent_exception () {
size_t actual_size = sizeof(__cxa_dependent_exception);
- void *ptr = do_malloc(actual_size);
+ void *ptr = __malloc_with_fallback(actual_size);
if (NULL == ptr)
std::terminate();
std::memset(ptr, 0, actual_size);
@@ -188,7 +172,7 @@ void * __cxa_allocate_dependent_exception () {
// This function shall free a dependent_exception.
// It does not affect the reference count of the primary exception.
void __cxa_free_dependent_exception (void * dependent_exception) {
- do_free(dependent_exception);
+ __free_with_fallback(dependent_exception);
}