diff options
Diffstat (limited to 'src/backend/jit/llvm')
-rw-r--r-- | src/backend/jit/llvm/llvmjit.c | 18 | ||||
-rw-r--r-- | src/backend/jit/llvm/llvmjit_error.cpp | 10 |
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. */ |