[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