[PATCH] expose install_fatal_error_handler() through the C API

Filip Pizlo fpizlo at apple.com
Wed Oct 16 18:37:37 PDT 2013


On Oct 16, 2013, at 4:59 PM, Tom Stellard <tom at stellard.net> wrote:

> On Wed, Oct 16, 2013 at 04:46:36PM -0700, Filip Pizlo wrote:
>> Hi!
>> 
>> If LLVM encounters badness it may call report_fatal_error().  The default behavior of this function is to call exit(1).  That doesn?t work out so great if LLVM is being used as a library in pretty much anything other than a command-line tool.  For example, if LLVM is in a daemon or in a UI app, calling exit(1) will bypass any stack trace or error reporting that the system would normally do for ?fatal? conditions.
>> 
>> Hence being able to override the behavior of report_fatal_error(), like what install_fatal_error_handler() does, is critical enough that it should be exposed via the C API.
>> 
>> This patch does that.
>> 
> 
> This isn't directly related to your patch, but since you appear to be
> using the error handling I'll ask in case you know:
> Why does report_fatal_error() still call exit() after the custom error
> handler?  Are there some applications that rely on this behavior?
> I've had it on my TODO list to look into this, but I haven't had time
> for it yet.

It seems that you have to do *something* after the call to the custom handler to preserve the guarantee that report_fatal_error() never returns.  This seems to accomplish that.

-Filip


> 
> Thanks,
> Tom
> 
>> I expose the API with some caveats:
>> 
>> - The C++ API involves a traditional void* opaque pointer for the fatal error callback.  The C API doesn?t do this.  I don?t think that the void* opaque pointer makes any sense since this is a global callback - there will only be one of them.  So if you need to pass some data to your callback, just put it in a global variable.
>> 
>> - The bindings will ignore the gen_crash_diag boolean.  I ignore it because (1) I don?t know what it does, (2) it?s not documented AFAIK, and (3) I couldn?t imagine any use for it.  I made the gut call that it probably wasn?t important enough to expose through the C API.
>> 
>> -Filip
>> 
>> 
> 
>> Index: include/llvm-c/Core.h
>> ===================================================================
>> --- include/llvm-c/Core.h	(revision 192567)
>> +++ include/llvm-c/Core.h	(working copy)
>> @@ -416,8 +416,24 @@
>> char *LLVMCreateMessage(const char *Message);
>> void LLVMDisposeMessage(char *Message);
>> 
>> +typedef void (*LLVMFatalErrorHandler)(const char *Reason);
>> 
>> /**
>> + * Install a fatal error handler. By default, if LLVM detects a fatal error, it
>> + * will call exit(1). This may not be appropriate in many contexts. For example,
>> + * doing exit(1) will bypass many crash reporting/tracing system tools. This
>> + * function allows you to install a callback that will be invoked prior to the
>> + * call to exit(1).
>> + */
>> +void LLVMInstallFatalErrorHandler(LLVMFatalErrorHandler Handler);
>> +
>> +/**
>> + * Reset the fatal error handler. This resets LLVM's fatal error handling
>> + * behavior to the default.
>> + */
>> +void LLVMResetFatalErrorHandler(void);
>> +
>> +/**
>>  * @defgroup LLVMCCoreContext Contexts
>>  *
>>  * Contexts are execution states for the core LLVM IR system.
>> Index: lib/Support/ErrorHandling.cpp
>> ===================================================================
>> --- lib/Support/ErrorHandling.cpp	(revision 192567)
>> +++ lib/Support/ErrorHandling.cpp	(working copy)
>> @@ -20,6 +20,7 @@
>> #include "llvm/Support/Signals.h"
>> #include "llvm/Support/Threading.h"
>> #include "llvm/Support/raw_ostream.h"
>> +#include "llvm-c/Core.h"
>> #include <cassert>
>> #include <cstdlib>
>> 
>> @@ -102,3 +103,19 @@
>>   LLVM_BUILTIN_UNREACHABLE;
>> #endif
>> }
>> +
>> +static void bindingsErrorHandler(void *user_data, const std::string& reason,
>> +                                 bool gen_crash_diag) {
>> +  LLVMFatalErrorHandler handler =
>> +    reinterpret_cast<LLVMFatalErrorHandler>(user_data);
>> +  handler(reason.c_str());
>> +}
>> +
>> +void LLVMInstallFatalErrorHandler(LLVMFatalErrorHandler Handler) {
>> +  install_fatal_error_handler(
>> +    bindingsErrorHandler, reinterpret_cast<void*>(Handler));
>> +}
>> +
>> +void LLVMResetFatalErrorHandler() {
>> +  remove_fatal_error_handler();
>> +}
> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 




More information about the llvm-commits mailing list