Skip to content

Commit

Permalink
Auto merge of #122574 - cuviper:llvm-oom, r=nikic
Browse files Browse the repository at this point in the history
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`.

Fixes #121305
Cc llvm/llvm-project#85281
r? `@nikic`
  • Loading branch information
bors committed Mar 16, 2024
2 parents 9023f90 + 8d374b1 commit 553506a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 3 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1519,7 +1519,7 @@ extern "C" {

#[link(name = "llvm-wrapper", kind = "static")]
extern "C" {
pub fn LLVMRustInstallFatalErrorHandler();
pub fn LLVMRustInstallErrorHandlers();
pub fn LLVMRustDisableSystemDialogsOnCrash();

// Create and destroy contexts.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ unsafe fn configure_llvm(sess: &Session) {
let mut llvm_c_strs = Vec::with_capacity(n_args + 1);
let mut llvm_args = Vec::with_capacity(n_args + 1);

llvm::LLVMRustInstallFatalErrorHandler();
llvm::LLVMRustInstallErrorHandlers();
// On Windows, an LLVM assertion will open an Abort/Retry/Ignore dialog
// box for the purpose of launching a debugger. However, on CI this will
// cause it to hang until it times out, which can take several hours.
Expand Down
25 changes: 24 additions & 1 deletion compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@

#include <iostream>

// for raw `write` in the bad-alloc handler
#ifdef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#endif

//===----------------------------------------------------------------------===
//
// This file defines alternate interfaces to core functions that are more
Expand Down Expand Up @@ -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";
(void)!::write(2, OOM, strlen(OOM));
(void)!::write(2, Reason, strlen(Reason));
(void)!::write(2, "\n", 1);
abort();
}

extern "C" void LLVMRustInstallErrorHandlers() {
install_bad_alloc_error_handler(BadAllocErrorHandler);
install_fatal_error_handler(FatalErrorHandler);
install_out_of_memory_new_handler();
}

extern "C" void LLVMRustDisableSystemDialogsOnCrash() {
Expand Down

0 comments on commit 553506a

Please sign in to comment.