{
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
if (proc_exit_inprogress)
return;
+ llvm_enter_fatal_on_oom();
+
if (llvm_context->module)
{
LLVMDisposeModule(llvm_context->module);
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)
}
}
+/*
+ * 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.
extern void llvm_enter_fatal_on_oom(void);
extern void llvm_leave_fatal_on_oom(void);
+extern bool llvm_in_fatal_on_oom(void);
extern void llvm_reset_after_error(void);
extern void llvm_assert_in_fatal_section(void);