[llvm-dev] Catching exceptions while unwinding through -fno-exceptions code

Reid Kleckner via llvm-dev llvm-dev at lists.llvm.org
Wed Dec 9 12:15:15 PST 2020


Bleh, early send. We'd also have to overcome the issue of functions being
nounwind with -fno-exceptions, which means LLVM would optimize those
invokes to calls immediately.

On Wed, Dec 9, 2020 at 12:14 PM Reid Kleckner <rnk at google.com> wrote:

> Using existing personality functions requires emitting an LLVM IR cleanup
> around every function when building in this -fterminate-exceptions mode.
> Then all functions would have IR like this:
>
> invoke void @foo(...) unwind to %terminate
> invoke void @bar(...) unwind to %terminate
> ...
> landingpad cleanup ...
>   call void @myterminate()
>
> On Tue, Dec 8, 2020 at 12:56 PM James Y Knight <jyknight at google.com>
> wrote:
>
>> Why is adding a new personality function useful? Can't you share a single
>> LSDA table for every noexcept function in a TU (both those implicitly
>> noexcept due to -fno-exceptions and for those marked "noexcept")?
>>
>> On Tue, Dec 8, 2020 at 1:05 PM Reid Kleckner via llvm-dev <
>> llvm-dev at lists.llvm.org> wrote:
>>
>>> I would suggest using a custom personality function for this. It will
>>> optimize better and be much smaller than using a standard personality
>>> function. It saves the LSDA tables.
>>>
>>> LLVM supports custom personality functions, so only clang changes are
>>> required. You could either do something like add a flag to override the EH
>>> personality with a custom one, or come up with a new dedicated
>>> fno-exceptions termination personality and add it to compiler-rt.
>>>
>>> On Mon, Dec 7, 2020 at 3:31 PM Modi Mo via llvm-dev <
>>> llvm-dev at lists.llvm.org> wrote:
>>>
>>>> If you don’t need to capture more information and can just terminate,
>>>> you can directly register std::terminate as the personality routine as
>>>> opposed to __gxx_personality_v0 or __CxxFrameHandler3/4 (Windows) which
>>>> lets you omit other metadata and work cross-platform.
>>>>
>>>>
>>>>
>>>> Modi
>>>>
>>>>
>>>>
>>>> *From: *llvm-dev <llvm-dev-bounces at lists.llvm.org> on behalf of
>>>> Everett Maus via llvm-dev <llvm-dev at lists.llvm.org>
>>>> *Reply-To: *Everett Maus <evmaus at google.com>
>>>> *Date: *Monday, December 7, 2020 at 12:47 PM
>>>> *To: *"llvm-dev at lists.llvm.org" <llvm-dev at lists.llvm.org>
>>>> *Subject: *[llvm-dev] Catching exceptions while unwinding through
>>>> -fno-exceptions code
>>>>
>>>>
>>>>
>>>> Hey all:
>>>>
>>>>
>>>>
>>>> I wanted to bring up something that was discussed a few years ago
>>>> around the behavior of exceptions when interacting with code compiled with
>>>> -fno-exceptions. (In
>>>> https://lists.llvm.org/pipermail/llvm-dev/2017-February/109992.html
>>>> and https://lists.llvm.org/pipermail/llvm-dev/2017-February/109995.html
>>>> )
>>>>
>>>>
>>>>
>>>> It's possible to compile (and link/etc.) code with -fexceptions for
>>>> some compilation units and -fno-exceptions for others.  Unlike the behavior
>>>> of noexcept (which requires termination), this doesn't have a specified
>>>> behavior in the C++ standard as far as I can tell.  However, it can lead to
>>>> memory leaks & other issues (e.x. with TSAN, it messes up the tracking of
>>>> the current stack frame).
>>>>
>>>>
>>>>
>>>> I'd be interested in looking into potentially doing the work to add an
>>>> option to clang/etc. to terminate when an exception traverses code compiled
>>>> with -fno-exceptions, instead of simply allowing the unwinder to walk
>>>> through the stack frame & leak memory/etc. (possibly behind a flag?).  This
>>>> particular issue bit a team I work closely with, and I'd imagine it could
>>>> be causing subtle issues for other clang users.
>>>>
>>>>
>>>>
>>>> I'm mostly concerned with solving this on Linux/x86_64, although if
>>>> there's a way to solve it more generally I'm open to looking into doing
>>>> that instead.
>>>>
>>>>
>>>>
>>>> I /think/ the right place to change this (from the discussions I
>>>> linked) would be in the LLVM -> assembly layer, adding an appropriate
>>>> .gcc_except_table for functions that are determined to be unable to throw
>>>> exceptions (either due to noexcept or due to -fno-exceptions). Then the
>>>> unwinder would find .eh_frame but no entry in the .gcc_except_table and
>>>> should terminate (via  __gxx_personality_v0).
>>>>
>>>>
>>>>
>>>> Am I understanding that correctly?  What's the best way to propose this
>>>> sort of change to clang? (document/just try to look at putting together a
>>>> PR/other?)
>>>>
>>>>
>>>>
>>>> Alternatively--one other thing that occurred to me is that it could be
>>>> reasonably cheap to simply add try/catch blocks that report an UBSAN error
>>>> in all methods that shouldn't be able to throw an exception.  This
>>>> obviously doesn't fix the code-generation problem and would lead to larger
>>>> binary sizes, but that seems less bad for an UBSAN build in particular.
>>>> That would likely meet my needs around wanting a way to automatically
>>>> detect this behavior/problem, but might not address the more generic issue.
>>>>
>>>>
>>>>
>>>> Thanks,
>>>>
>>>> --
>>>>
>>>> --EJM
>>>> _______________________________________________
>>>> LLVM Developers mailing list
>>>> llvm-dev at lists.llvm.org
>>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> llvm-dev at lists.llvm.org
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20201209/6e6f4142/attachment.html>


More information about the llvm-dev mailing list