Right, this gets into the whole error-handling philosophy of LLVM, or
lack thereof. The idea is that so long as your frontend generating IR
gives correct IR and is well-behaved, LLVM will not assert, abort, or
crash. Once you've successfully debugged your frontend, you should
never see this kind of error from LLVM and need to recover from it.
In practice, this is true enough that it is acceptable to simply crash
the process when it fails.
One problem with installing a SIGABRT handler and raising an exception
is that code in LLVM is written with these assumptions about error
handling. It isn't expecting a failing assert to raise a C++
exception, so it doesn't do any work to clean up if that were to
happen. Memory is left in an unknown state, and attempting to perform
another compilation might just lead to a crash later.
Also, most people deploy LLVM with the asserts disabled because they
make the code ~10x slower. For unladen swallow, I tend to run our
regression tests with asserts off so they finish faster, and if it
crashes, I might go back and turn them on.
Reid
On Fri, Jun 18, 2010 at 6:33 AM, Curtis Faith <curtis at curtisfaith.com>
wrote:> I'm trying to figure out the best way to handle signals raised during
the
> execution of LLVM's optimization passes or the JIT'ing of code
prior to
> running it.
> In particular, LLVM throws unix signals instead of C++ exceptions while the
> header ErrorHandling.h contains the following warning (the last paragraph
in
> particular):
> /// llvm_instal_error_handler - Installs a new error handler to be used
> /// whenever a serious (non-recoverable) error is encountered by LLVM.
> ///
> /// (snip)
> ///
> /// It is dangerous to naively use an error handler which throws an
> exception.
> /// Even though some applications desire to gracefully recover from
> arbitrary
> /// faults, blindly throwing exceptions through unfamiliar code isn't
a
> way to
> /// achieve this.
> I must be naive because what I'd really like to do is throw an
exception. I
> realize there are good reasons that this might not work so I understand the
> comment, however, I'm curious why LLVM didn't use C++ exceptions
for error
> recovery rather than unix signals like SIGABRT?
> I figured this must have come up a few times so I did the usual Google
> search but didn't find any definitive relevant discussions, though I
found
> plenty of references to the fact that LLVM uses signals and other people
who
> wondered why. I never found a good answer nor a definitive statement of the
> best approach for this particular case.
> So, given the fact of the current design choice, which I'm in no real
> position to argue was a good one or a bad one since I don't know the
> criteria, I want to know the best way to handle signals generated while
I'm
> JIT'ing LLVM IR that I generated from a scripting language that I parse
and
> output to LLVM IR within my C++ engine (which also happens to reside within
> a Cocoa Objective-C application world).
> Ideally, I'd like to catch the signal inside a single C++ function that
> calls the JIT'ing code and handles the error if something goes wrong. I
> don't want to have to take my process down in that event. This code
will be
> running in the same process as the user GUI, some of the time, so I
can't
> just kill the process when that is the case.
> I know others must have faced the same issue when using LLVM for embedded
> scripting language JIT compilation. What's the best way to encapsulate
and
> recover from errors that occur within the LLVM JIT framework whether
because
> of my unintentional misuse of the IR or a bug in LLVM itself?
> Thanks in advance,
> Curtis
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
>