[llvm] r325426 - Report fatal error in the case of out of memory

Serge Pavlov via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 17 02:21:34 PST 2018


Author: sepavloff
Date: Sat Feb 17 02:21:33 2018
New Revision: 325426

URL: http://llvm.org/viewvc/llvm-project?rev=325426&view=rev
Log:
Report fatal error in the case of out of memory

This is partial recommit of r325224, reverted in 325227. The relevant
part of original comment is below.

Analysis of fails in the case of out of memory errors can be tricky on
Windows. Such error emerges at the point where memory allocation function
fails, but manifests itself when null pointer is used. These two points
may be distant from each other. Besides, next runs may not exhibit
allocation error.

Usual programming practice does not require checking result of 'operator
new' because it throws 'std::bad_alloc' in the case of allocation error.
However, LLVM is usually built with exceptions turned off, so 'new' can
return null pointer. This change installs custom new handler, which causes
fatal error in the case of out of memory. The handler is installed
automatically prior to call to 'main' during construction of a static
object defined in 'lib/Support/ErrorHandling.cpp'. If the application does
not use this file, the handler may be installed manually by a call to
'llvm::install_out_of_memory_new_handler', declared in
'include/llvm/Support/ErrorHandling.h".

Differential Revision: https://reviews.llvm.org/D43010

Modified:
    llvm/trunk/include/llvm/Support/ErrorHandling.h
    llvm/trunk/lib/Support/ErrorHandling.cpp

Modified: llvm/trunk/include/llvm/Support/ErrorHandling.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ErrorHandling.h?rev=325426&r1=325425&r2=325426&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ErrorHandling.h (original)
+++ llvm/trunk/include/llvm/Support/ErrorHandling.h Sat Feb 17 02:21:33 2018
@@ -100,6 +100,8 @@ void install_bad_alloc_error_handler(fat
 /// Restores default bad alloc error handling behavior.
 void remove_bad_alloc_error_handler();
 
+void install_out_of_memory_new_handler();
+
 /// Reports a bad alloc error, calling any user defined bad alloc
 /// error handler. In contrast to the generic 'report_fatal_error'
 /// functions, this function is expected to return, e.g. the user

Modified: llvm/trunk/lib/Support/ErrorHandling.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ErrorHandling.cpp?rev=325426&r1=325425&r2=325426&view=diff
==============================================================================
--- llvm/trunk/lib/Support/ErrorHandling.cpp (original)
+++ llvm/trunk/lib/Support/ErrorHandling.cpp Sat Feb 17 02:21:33 2018
@@ -175,6 +175,39 @@ void llvm::report_bad_alloc_error(const
 #endif
 }
 
+#ifdef LLVM_ENABLE_EXCEPTIONS
+// Do not set custom new handler if exceptions are enabled. In this case OOM
+// errors are handled by throwing 'std::bad_alloc'.
+void llvm::install_out_of_memory_new_handler() {
+}
+#else
+// Causes crash on allocation failure. It is called prior to the handler set by
+// 'install_bad_alloc_error_handler'.
+static void out_of_memory_new_handler() {
+  llvm::report_bad_alloc_error("Allocation failed");
+}
+
+// Installs new handler that causes crash on allocation failure. It does not
+// need to be called explicitly, if this file is linked to application, because
+// in this case it is called during construction of 'new_handler_installer'.
+void llvm::install_out_of_memory_new_handler() {
+  static bool out_of_memory_new_handler_installed = false;
+  if (!out_of_memory_new_handler_installed) {
+    std::set_new_handler(out_of_memory_new_handler);
+    out_of_memory_new_handler_installed = true;
+  }
+}
+
+// Static object that causes installation of 'out_of_memory_new_handler' before
+// execution of 'main'.
+static class NewHandlerInstaller {
+public:
+  NewHandlerInstaller() {
+    install_out_of_memory_new_handler();
+  }
+} new_handler_installer;
+#endif
+
 void llvm::llvm_unreachable_internal(const char *msg, const char *file,
                                      unsigned line) {
   // This code intentionally doesn't call the ErrorHandler callback, because




More information about the llvm-commits mailing list