[PATCH] D17815: [libc++abi] Use fallback_malloc to allocate __cxa_eh_globals in case of dynamic memory exhaustion.
Igor Kudrin via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 2 09:07:33 PST 2016
ikudrin created this revision.
ikudrin added reviewers: mclow.lists, howard.hinnant, EricWF.
ikudrin added a subscriber: cfe-commits.
Throwing an exception for the first time may lead to calling calloc to allocate memory for __cxa_eh_globals. If the memory pool at that moment is exhausted, it results in abnormal termination of the program.
This patch addresses the issue by using fallback_malloc in that case.
http://reviews.llvm.org/D17815
Files:
libcxxabi/trunk/src/cxa_exception_storage.cpp
libcxxabi/trunk/test/test_exception_storage_nodynmem.pass.cpp
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 <cstdlib>
+
+// 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;
+}
Index: libcxxabi/trunk/src/cxa_exception_storage.cpp
===================================================================
--- libcxxabi/trunk/src/cxa_exception_storage.cpp
+++ libcxxabi/trunk/src/cxa_exception_storage.cpp
@@ -46,19 +46,38 @@
#include <pthread.h>
#include <cstdlib> // for calloc, free
+#include <cstring> // for memset
#include "abort_message.h"
// In general, we treat all pthread errors as fatal.
// We cannot call std::terminate() because that will in turn
// 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 ) )
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D17815.49628.patch
Type: text/x-patch
Size: 2737 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160302/c80f7b2a/attachment.bin>
More information about the cfe-commits
mailing list