about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndy Russell <arussell123@gmail.com>2018-10-12 15:35:55 -0400
committerAndy Russell <arussell123@gmail.com>2018-10-12 17:29:40 -0400
commit00e1f5b8df5382a7296ba463a8e53ce55bf4c6a5 (patch)
tree2ec2525efd16d091c0d6f3647f6c8c8aa29c5d74
parente9e27e6a6258b3adf00a5dd35d2676656224880d (diff)
downloadrust-00e1f5b8df5382a7296ba463a8e53ce55bf4c6a5.tar.gz
rust-00e1f5b8df5382a7296ba463a8e53ce55bf4c6a5.zip
exit with status code 101 on fatal LLVM error
Fixes #54992.
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs2
-rw-r--r--src/librustc_codegen_llvm/llvm_util.rs2
-rw-r--r--src/rustllvm/RustWrapper.cpp24
3 files changed, 28 insertions, 0 deletions
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index c9f51efdc50..6108af6c884 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -482,6 +482,8 @@ pub mod debuginfo {
 extern { pub type ModuleBuffer; }
 
 extern "C" {
+    pub fn LLVMRustInstallFatalErrorHandler();
+
     // Create and destroy contexts.
     pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context;
     pub fn LLVMContextDispose(C: &'static mut Context);
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 8456cf2f480..0a80fdddbf9 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -56,6 +56,8 @@ 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();
+
     {
         let mut add = |arg: &str| {
             let s = CString::new(arg).unwrap();
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 2b1bf1c0290..bf7afa1b6c0 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -17,6 +17,7 @@
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Bitcode/BitcodeWriterPass.h"
+#include "llvm/Support/Signals.h"
 
 #include "llvm/IR/CallSite.h"
 
@@ -26,6 +27,8 @@
 #include <cstdlib>
 #endif
 
+#include <iostream>
+
 //===----------------------------------------------------------------------===
 //
 // This file defines alternate interfaces to core functions that are more
@@ -62,6 +65,27 @@ static AtomicOrdering fromRust(LLVMAtomicOrdering Ordering) {
 
 static LLVM_THREAD_LOCAL char *LastError;
 
+// Custom error handler for fatal LLVM errors.
+//
+// Notably it exits the process with code 101, unlike LLVM's default of 1.
+static void FatalErrorHandler(void *UserData,
+                              const std::string& Reason,
+                              bool GenCrashDiag) {
+  // Do the same thing that the default error handler does.
+  std::cerr << "LLVM ERROR: " << Reason << std::endl;
+
+  // Since this error handler exits the process, we have to run any cleanup that
+  // LLVM would run after handling the error. This might change with an LLVM
+  // upgrade.
+  sys::RunInterruptHandlers();
+
+  exit(101);
+}
+
+extern "C" void LLVMRustInstallFatalErrorHandler() {
+  install_fatal_error_handler(FatalErrorHandler);
+}
+
 extern "C" LLVMMemoryBufferRef
 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =