summaryrefslogtreecommitdiff
path: root/src/backend/jit/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/jit/llvm')
-rw-r--r--src/backend/jit/llvm/llvmjit.c18
-rw-r--r--src/backend/jit/llvm/llvmjit_error.cpp10
2 files changed, 26 insertions, 2 deletions
diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c
index 638574f480..120f5239c9 100644
--- a/src/backend/jit/llvm/llvmjit.c
+++ b/src/backend/jit/llvm/llvmjit.c
@@ -184,8 +184,6 @@ llvm_release_context(JitContext *context)
{
LLVMJitContext *llvm_context = (LLVMJitContext *) context;
- llvm_enter_fatal_on_oom();
-
/*
* When this backend is exiting, don't clean up LLVM. As an error might
* have occurred from within LLVM, we do not want to risk reentering. All
@@ -194,6 +192,8 @@ llvm_release_context(JitContext *context)
if (proc_exit_inprogress)
return;
+ llvm_enter_fatal_on_oom();
+
if (llvm_context->module)
{
LLVMDisposeModule(llvm_context->module);
@@ -850,6 +850,20 @@ llvm_session_initialize(void)
static void
llvm_shutdown(int code, Datum arg)
{
+ /*
+ * If llvm_shutdown() is reached while in a fatal-on-oom section an error
+ * has occurred in the middle of LLVM code. It is not safe to call back
+ * into LLVM (which is why a FATAL error was thrown).
+ *
+ * We do need to shutdown LLVM in other shutdown cases, otherwise
+ * e.g. profiling data won't be written out.
+ */
+ if (llvm_in_fatal_on_oom())
+ {
+ Assert(proc_exit_inprogress);
+ return;
+ }
+
#if LLVM_VERSION_MAJOR > 11
{
if (llvm_opt3_orc)
diff --git a/src/backend/jit/llvm/llvmjit_error.cpp b/src/backend/jit/llvm/llvmjit_error.cpp
index 9c6e8026e7..adfca4a708 100644
--- a/src/backend/jit/llvm/llvmjit_error.cpp
+++ b/src/backend/jit/llvm/llvmjit_error.cpp
@@ -84,6 +84,16 @@ llvm_leave_fatal_on_oom(void)
}
/*
+ * Are we currently in an fatal-on-oom section? Useful to skip cleanup in case
+ * of errors.
+ */
+bool
+llvm_in_fatal_on_oom(void)
+{
+ return fatal_new_handler_depth > 0;
+}
+
+/*
* Reset fatal error handling. This should only be called in error recovery
* loops like PostgresMain()'s.
*/