Skip to content

Commit 33b4ed2

Browse files
authored
Rollup merge of rust-lang#122574 - cuviper:llvm-oom, r=nikic
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 rust-lang#121305 Cc llvm/llvm-project#85281 r? ``@nikic``
2 parents ea07456 + 8d374b1 commit 33b4ed2

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1519,7 +1519,7 @@ extern "C" {
15191519

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

15251525
// Create and destroy contexts.

compiler/rustc_codegen_llvm/src/llvm_util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ unsafe fn configure_llvm(sess: &Session) {
4949
let mut llvm_c_strs = Vec::with_capacity(n_args + 1);
5050
let mut llvm_args = Vec::with_capacity(n_args + 1);
5151

52-
llvm::LLVMRustInstallFatalErrorHandler();
52+
llvm::LLVMRustInstallErrorHandlers();
5353
// On Windows, an LLVM assertion will open an Abort/Retry/Ignore dialog
5454
// box for the purpose of launching a debugger. However, on CI this will
5555
// cause it to hang until it times out, which can take several hours.

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+24-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525

2626
#include <iostream>
2727

28+
// for raw `write` in the bad-alloc handler
29+
#ifdef _MSC_VER
30+
#include <io.h>
31+
#else
32+
#include <unistd.h>
33+
#endif
34+
2835
//===----------------------------------------------------------------------===
2936
//
3037
// This file defines alternate interfaces to core functions that are more
@@ -88,8 +95,24 @@ static void FatalErrorHandler(void *UserData,
8895
exit(101);
8996
}
9097

91-
extern "C" void LLVMRustInstallFatalErrorHandler() {
98+
// Custom error handler for bad-alloc LLVM errors.
99+
//
100+
// It aborts the process without any further allocations, similar to LLVM's
101+
// default except that may be configured to `throw std::bad_alloc()` instead.
102+
static void BadAllocErrorHandler(void *UserData,
103+
const char* Reason,
104+
bool GenCrashDiag) {
105+
const char *OOM = "rustc-LLVM ERROR: out of memory\n";
106+
(void)!::write(2, OOM, strlen(OOM));
107+
(void)!::write(2, Reason, strlen(Reason));
108+
(void)!::write(2, "\n", 1);
109+
abort();
110+
}
111+
112+
extern "C" void LLVMRustInstallErrorHandlers() {
113+
install_bad_alloc_error_handler(BadAllocErrorHandler);
92114
install_fatal_error_handler(FatalErrorHandler);
115+
install_out_of_memory_new_handler();
93116
}
94117

95118
extern "C" void LLVMRustDisableSystemDialogsOnCrash() {

0 commit comments

Comments
 (0)