Skip to content

Commit df0d6ad

Browse files
committed
Auto merge of rust-lang#55023 - euclio:llvm-error-handler, r=cuviper
Exit with code 101 on fatal codegen errors Fixes rust-lang#54992. This PR installs a custom fatal error handler that prints the error from LLVM and exits with 101. There should be no visible change in the output from LLVM. This allows distinguishing a fatal LLVM error with a compilation error by exit code. This PR also modifies the LLVM codegen backend to ICE instead of emitting a fatal error when encountering a LLVM worker thread panic for the same reason. r? @cuviper
2 parents 46880f4 + 1811f13 commit df0d6ad

File tree

4 files changed

+30
-4
lines changed

4 files changed

+30
-4
lines changed

src/librustc_codegen_llvm/back/write.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -2031,9 +2031,7 @@ fn start_executing_work(tcx: TyCtxt,
20312031
main_thread_worker_state = MainThreadWorkerState::Idle;
20322032
}
20332033
Message::Done { result: Err(()), worker_id: _ } => {
2034-
shared_emitter.fatal("aborting due to worker thread failure");
2035-
// Exit the coordinator thread
2036-
return Err(())
2034+
bug!("worker thread panicked");
20372035
}
20382036
Message::CodegenItem => {
20392037
bug!("the coordinator should not receive codegen requests")
@@ -2392,7 +2390,7 @@ impl OngoingCodegen {
23922390
panic!("expected abort due to worker thread errors")
23932391
},
23942392
Err(_) => {
2395-
sess.fatal("Error during codegen/LLVM phase.");
2393+
bug!("panic during codegen/LLVM phase");
23962394
}
23972395
};
23982396

src/librustc_codegen_llvm/llvm/ffi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,8 @@ pub mod debuginfo {
482482
extern { pub type ModuleBuffer; }
483483

484484
extern "C" {
485+
pub fn LLVMRustInstallFatalErrorHandler();
486+
485487
// Create and destroy contexts.
486488
pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context;
487489
pub fn LLVMContextDispose(C: &'static mut Context);

src/librustc_codegen_llvm/llvm_util.rs

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ unsafe fn configure_llvm(sess: &Session) {
5656
let mut llvm_c_strs = Vec::with_capacity(n_args + 1);
5757
let mut llvm_args = Vec::with_capacity(n_args + 1);
5858

59+
llvm::LLVMRustInstallFatalErrorHandler();
60+
5961
{
6062
let mut add = |arg: &str| {
6163
let s = CString::new(arg).unwrap();

src/rustllvm/RustWrapper.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/Object/Archive.h"
1818
#include "llvm/Object/ObjectFile.h"
1919
#include "llvm/Bitcode/BitcodeWriterPass.h"
20+
#include "llvm/Support/Signals.h"
2021

2122
#include "llvm/IR/CallSite.h"
2223

@@ -26,6 +27,8 @@
2627
#include <cstdlib>
2728
#endif
2829

30+
#include <iostream>
31+
2932
//===----------------------------------------------------------------------===
3033
//
3134
// This file defines alternate interfaces to core functions that are more
@@ -62,6 +65,27 @@ static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
6265

6366
static LLVM_THREAD_LOCAL char *LastError;
6467

68+
// Custom error handler for fatal LLVM errors.
69+
//
70+
// Notably it exits the process with code 101, unlike LLVM's default of 1.
71+
static void FatalErrorHandler(void *UserData,
72+
const std::string& Reason,
73+
bool GenCrashDiag) {
74+
// Do the same thing that the default error handler does.
75+
std::cerr << "LLVM ERROR: " << Reason << std::endl;
76+
77+
// Since this error handler exits the process, we have to run any cleanup that
78+
// LLVM would run after handling the error. This might change with an LLVM
79+
// upgrade.
80+
sys::RunInterruptHandlers();
81+
82+
exit(101);
83+
}
84+
85+
extern "C" void LLVMRustInstallFatalErrorHandler() {
86+
install_fatal_error_handler(FatalErrorHandler);
87+
}
88+
6589
extern "C" LLVMMemoryBufferRef
6690
LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
6791
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =

0 commit comments

Comments
 (0)