From 0ade5a11f5705e33e031ae5b47c21fd0553d6675 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 15 Mar 2024 15:49:06 -0700 Subject: Register LLVM handlers for bad-alloc / OOM LLVM's default bad-alloc handler may throw if exceptions are enabled, and `operator new` isn't hooked at all by default. Now we register our own handler that prints a message similar to fatal errors, then aborts. We also call the function that registers the C++ `std::new_handler`. --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 25 +++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp') diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 1632b9e1249..072620c65a5 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -25,6 +25,13 @@ #include +// for raw `write` in the bad-alloc handler +#ifdef _MSC_VER +#include +#else +#include +#endif + //===----------------------------------------------------------------------=== // // This file defines alternate interfaces to core functions that are more @@ -88,8 +95,24 @@ static void FatalErrorHandler(void *UserData, exit(101); } -extern "C" void LLVMRustInstallFatalErrorHandler() { +// Custom error handler for bad-alloc LLVM errors. +// +// It aborts the process without any further allocations, similar to LLVM's +// default except that may be configured to `throw std::bad_alloc()` instead. +static void BadAllocErrorHandler(void *UserData, + const char* Reason, + bool GenCrashDiag) { + const char *OOM = "rustc-LLVM ERROR: out of memory\n"; + write(2, OOM, strlen(OOM)); + write(2, Reason, strlen(Reason)); + write(2, "\n", 1); + abort(); +} + +extern "C" void LLVMRustInstallErrorHandlers() { install_fatal_error_handler(FatalErrorHandler); + install_bad_alloc_error_handler(BadAllocErrorHandler); + install_out_of_memory_new_handler(); } extern "C" void LLVMRustDisableSystemDialogsOnCrash() { -- cgit 1.4.1-3-g733a5 From adf57a75d5014b620f2c09587b6e1e108a7622da Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 15 Mar 2024 16:48:16 -0700 Subject: Aggressively ignore write errors during bad-alloc --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp') diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 072620c65a5..861c0a6e79a 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -103,9 +103,9 @@ static void BadAllocErrorHandler(void *UserData, const char* Reason, bool GenCrashDiag) { const char *OOM = "rustc-LLVM ERROR: out of memory\n"; - write(2, OOM, strlen(OOM)); - write(2, Reason, strlen(Reason)); - write(2, "\n", 1); + (void)!::write(2, OOM, strlen(OOM)); + (void)!::write(2, Reason, strlen(Reason)); + (void)!::write(2, "\n", 1); abort(); } -- cgit 1.4.1-3-g733a5 From 8d374b1f2af876423435e47b66c01cd6fa38aaa1 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 15 Mar 2024 16:49:08 -0700 Subject: Install the bad-alloc handler before fatal errors The bad-alloc installer was incorrectly asserting that the other handler isn't set yet, instead of checking its own, but we can avoid that by changing the order we install them. Ref: https://github.com/llvm/llvm-project/issues/83040 --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp') diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 861c0a6e79a..91f54da5c12 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -110,8 +110,8 @@ static void BadAllocErrorHandler(void *UserData, } extern "C" void LLVMRustInstallErrorHandlers() { - install_fatal_error_handler(FatalErrorHandler); install_bad_alloc_error_handler(BadAllocErrorHandler); + install_fatal_error_handler(FatalErrorHandler); install_out_of_memory_new_handler(); } -- cgit 1.4.1-3-g733a5